Loading config/schema/group.schema.yml +5 −8 Changes for config/schema/group.schema.yml: 5 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -66,18 +66,15 @@ group.role.*: admin: type: 'boolean' label: 'Group role is an admin role' internal: type: 'boolean' label: 'Group role is used internally' audience: scope: type: 'string' label: 'The scope of the group role' global_role: type: 'string' label: 'Audience' label: 'The global role the group role synchronizes with. Only applies if scope is outsider or insider' group_type: type: 'string' label: 'Group type ID' permissions_ui: type: 'boolean' label: 'Show this role in the default permissions UI' permissions: type: 'sequence' label: 'Permissions' Loading group.install +122 −0 Changes for group.install: 122 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -5,7 +5,9 @@ * Install, update and uninstall functions for the group module. */ use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\group\Entity\GroupTypeInterface; /** * Implements hook_update_last_removed(). Loading Loading @@ -102,3 +104,123 @@ function group_update_9203() { $role->save(TRUE); } } /** * Convert synchronized group roles to new scope and target_role structure. */ function group_update_9204() { $config_factory = \Drupal::configFactory(); $synchronized_role_ids = []; foreach ($config_factory->listAll('user.role.') as $role_config_name) { $role_id = $config_factory->get($role_config_name)->get('id'); // We never synced any roles to anonymous or authenticated. if ($role_id === 'anonymous' || $role_id === 'authenticated') { continue; } $synchronized_role_ids[] = $role_id; } // Nothing to update if we had no user defined global roles. if (empty($synchronized_role_ids)) { return; } foreach ($config_factory->listAll('group.type.') as $group_type_config_name) { $group_type_id = $config_factory->get($group_type_config_name)->get('id'); foreach ($synchronized_role_ids as $role_id) { // Copied the group role ID logic directly from the GroupRoleSynchronizer // class because that class has been removed in favor of the new roles. $machine_name_max_length = EntityTypeInterface::ID_MAX_LENGTH - GroupTypeInterface::ID_MAX_LENGTH - 1; $machine_name = substr(md5('group_role_sync.' . $role_id), 0, $machine_name_max_length); $group_role_id = "$group_type_id-$machine_name"; // Delete the synchronized role if they had no rights. $group_role = $config_factory->getEditable('group.role.' . $group_role_id); if (!$group_role->get('admin') && empty($group_role->get('permissions'))) { $group_role->delete(); } // Otherwise update the group role to use the new keys. else { $group_role->set('scope', 'outsider'); $group_role->set('global_role', $role_id); // Clear the old keys and save. $group_role->clear('permissions_ui'); $group_role->clear('internal'); $group_role->clear('audience'); $group_role->save(TRUE); } } } } /** * Convert default group roles to new scope and target_role structure. */ function group_update_9205() { $config_factory = \Drupal::configFactory(); $group_role_info = [ 'anonymous' => [ 'scope' => 'outsider', 'global_role' => 'anonymous', ], 'outsider' => [ 'scope' => 'outsider', 'global_role' => 'authenticated', ], 'member' => [ 'scope' => 'insider', 'global_role' => 'authenticated', ], ]; // Update anonymous, outsider and member. foreach ($config_factory->listAll('group.type.') as $group_type_config_name) { $group_type_id = $config_factory->get($group_type_config_name)->get('id'); foreach ($group_role_info as $group_role_suffix => $info) { $group_role_id = "$group_type_id-$group_role_suffix"; // We do not delete the default roles, even if they have no rights. $group_role = $config_factory->getEditable('group.role.' . $group_role_id); $group_role->set('scope', $info['scope']); $group_role->set('global_role', $info['global_role']); // Clear the old keys and save. $group_role->clear('permissions_ui'); $group_role->clear('internal'); $group_role->clear('audience'); $group_role->save(TRUE); } } } /** * Convert user created group roles to new scope and target_role structure. */ function group_update_9206() { $config_factory = \Drupal::configFactory(); foreach ($config_factory->listAll('group.role.') as $config_name) { // Now that we've updated synchronized and default roles, any role that // still has the old properties is a user generated one. So skip the rest. if (empty($config_factory->get($config_name)->get('audience'))) { continue; } // We do not delete the user created roles, even if they have no rights. $group_role = $config_factory->getEditable($config_name); $group_role->set('scope', 'individual'); // Clear the old keys and save. $group_role->clear('permissions_ui'); $group_role->clear('internal'); $group_role->clear('audience'); $group_role->save(TRUE); } } group.links.task.yml +0 −14 Changes for group.links.task.yml: 0 added lines, 14 removed lines. Original line number Diff line number Diff line Loading @@ -59,20 +59,6 @@ group_type.permissions_form: base_route: 'entity.group_type.edit_form' weight: 15 group_type.permissions_form.basic: title: 'Basic permissions' route_name: 'entity.group_type.permissions_form' base_route: 'entity.group_type.edit_form' parent_id: 'group_type.permissions_form' weight: 0 group_type.permissions_form.outsider: title: 'Advanced outsider permissions' route_name: 'entity.group_type.outsider_permissions_form' base_route: 'entity.group_type.edit_form' parent_id: 'group_type.permissions_form' weight: 5 group_type.roles_list: title: 'Roles' route_name: 'entity.group_role.collection' Loading group.module +28 −51 Changes for group.module: 28 added lines, 51 removed lines. Original line number Diff line number Diff line Loading @@ -19,7 +19,8 @@ use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Session\AccountInterface; use Drupal\group\Entity\GroupContent; use Drupal\group\QueryAccess\EntityQueryAlter; use Drupal\user\RoleInterface; use Drupal\group\QueryAccess\GroupContentQueryAlter; use Drupal\group\QueryAccess\GroupQueryAlter; use Drupal\views\Plugin\views\query\QueryPluginBase; use Drupal\views\Plugin\views\query\Sql; use Drupal\views\ViewExecutable; Loading Loading @@ -184,11 +185,6 @@ function template_preprocess_group_content(&$variables) { */ function group_rebuild() { _group_relation_type_manager()->installEnforced(); /** @var \Drupal\group\Entity\Storage\GroupRoleStorageInterface $storage */ $storage = \Drupal::entityTypeManager()->getStorage('group_role'); $storage->createInternal(); $storage->createSynchronized(); } /** Loading @@ -198,11 +194,6 @@ function group_modules_installed($modules) { // Only create config objects while config import is not in progress. if (!\Drupal::isConfigSyncing()) { _group_relation_type_manager()->installEnforced(); /** @var \Drupal\group\Entity\Storage\GroupRoleStorageInterface $storage */ $storage = \Drupal::entityTypeManager()->getStorage('group_role'); $storage->createInternal(); $storage->createSynchronized(); } } Loading Loading @@ -245,8 +236,33 @@ function group_query_entity_query_alter(SelectInterface $query) { $entity_type_manager = \Drupal::entityTypeManager(); $entity_type = $entity_type_manager->getDefinition($entity_type_id); // Add specific access checks based on the entity type. Please note that we // first check for the group and group content entity types because we have // full control over those and can therefore optimize the query more. If the // query is for a different entity type, we fall back to the default query // alter. // // PLEASE KEEP IN MIND that this means that a plugin that allows you to nest // groups will have no query access added for nested groups whatsoever. This // is by design as those plugins should opt to use the permission calculator // system, as it's way faster and automatically included in GroupQueryAlter. // // @todo Enforce that plugins may not define entity_access for "group". switch ($entity_type_id) { case 'group': $class_name = GroupQueryAlter::class; break; case 'group_content': $class_name = GroupContentQueryAlter::class; break; default: $class_name = EntityQueryAlter::class; } \Drupal::service('class_resolver') ->getInstanceFromDefinition(EntityQueryAlter::class) ->getInstanceFromDefinition($class_name) ->alter($query, $entity_type); } } Loading Loading @@ -501,33 +517,6 @@ function group_user_delete(EntityInterface $account) { } } /** * Implements hook_ENTITY_TYPE_insert(). */ function group_user_role_insert(RoleInterface $role) { // Only create config objects while config import is not in progress. if (!\Drupal::isConfigSyncing()) { /** @var \Drupal\group\Entity\Storage\GroupRoleStorageInterface $storage */ $storage = \Drupal::entityTypeManager()->getStorage('group_role'); $storage->createSynchronized(NULL, [$role->id()]); } } /** * Implements hook_ENTITY_TYPE_update(). */ function group_user_role_update(RoleInterface $role) { /** @var \Drupal\User\RoleInterface $original */ $original = $role->original; // Update the group roles if the user role label changed. if ($role->label() != $original->label()) { /** @var \Drupal\group\Entity\Storage\GroupRoleStorageInterface $storage */ $storage = \Drupal::entityTypeManager()->getStorage('group_role'); $storage->updateSynchronizedLabels($role); } } /** * Implements hook_form_alter(). */ Loading Loading @@ -706,18 +695,6 @@ function _group_relation_type_manager() { return \Drupal::service('group_relation_type.manager'); } /** * Gets the group role synchronizer service. * * @return \Drupal\group\GroupRoleSynchronizerInterface * The group role synchronizer service. * * @internal Try to properly inject the service when possible. */ function _group_role_synchronizer() { return \Drupal::service('group_role.synchronizer'); } /** * Implements hook_ENTITY_TYPE_presave(). * Loading group.routing.yml +0 −8 Changes for group.routing.yml: 0 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -54,14 +54,6 @@ entity.group_type.permissions_form: requirements: _permission: 'administer group' entity.group_type.outsider_permissions_form: path: '/admin/group/types/manage/{group_type}/permissions/outsider' defaults: _form: '\Drupal\group\Form\GroupPermissionsOutsiderForm' _title: 'Edit advanced outsider permissions' requirements: _permission: 'administer group' entity.group_type.content_plugins: path: '/admin/group/types/manage/{group_type}/content' defaults: Loading Loading
config/schema/group.schema.yml +5 −8 Changes for config/schema/group.schema.yml: 5 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -66,18 +66,15 @@ group.role.*: admin: type: 'boolean' label: 'Group role is an admin role' internal: type: 'boolean' label: 'Group role is used internally' audience: scope: type: 'string' label: 'The scope of the group role' global_role: type: 'string' label: 'Audience' label: 'The global role the group role synchronizes with. Only applies if scope is outsider or insider' group_type: type: 'string' label: 'Group type ID' permissions_ui: type: 'boolean' label: 'Show this role in the default permissions UI' permissions: type: 'sequence' label: 'Permissions' Loading
group.install +122 −0 Changes for group.install: 122 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -5,7 +5,9 @@ * Install, update and uninstall functions for the group module. */ use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\group\Entity\GroupTypeInterface; /** * Implements hook_update_last_removed(). Loading Loading @@ -102,3 +104,123 @@ function group_update_9203() { $role->save(TRUE); } } /** * Convert synchronized group roles to new scope and target_role structure. */ function group_update_9204() { $config_factory = \Drupal::configFactory(); $synchronized_role_ids = []; foreach ($config_factory->listAll('user.role.') as $role_config_name) { $role_id = $config_factory->get($role_config_name)->get('id'); // We never synced any roles to anonymous or authenticated. if ($role_id === 'anonymous' || $role_id === 'authenticated') { continue; } $synchronized_role_ids[] = $role_id; } // Nothing to update if we had no user defined global roles. if (empty($synchronized_role_ids)) { return; } foreach ($config_factory->listAll('group.type.') as $group_type_config_name) { $group_type_id = $config_factory->get($group_type_config_name)->get('id'); foreach ($synchronized_role_ids as $role_id) { // Copied the group role ID logic directly from the GroupRoleSynchronizer // class because that class has been removed in favor of the new roles. $machine_name_max_length = EntityTypeInterface::ID_MAX_LENGTH - GroupTypeInterface::ID_MAX_LENGTH - 1; $machine_name = substr(md5('group_role_sync.' . $role_id), 0, $machine_name_max_length); $group_role_id = "$group_type_id-$machine_name"; // Delete the synchronized role if they had no rights. $group_role = $config_factory->getEditable('group.role.' . $group_role_id); if (!$group_role->get('admin') && empty($group_role->get('permissions'))) { $group_role->delete(); } // Otherwise update the group role to use the new keys. else { $group_role->set('scope', 'outsider'); $group_role->set('global_role', $role_id); // Clear the old keys and save. $group_role->clear('permissions_ui'); $group_role->clear('internal'); $group_role->clear('audience'); $group_role->save(TRUE); } } } } /** * Convert default group roles to new scope and target_role structure. */ function group_update_9205() { $config_factory = \Drupal::configFactory(); $group_role_info = [ 'anonymous' => [ 'scope' => 'outsider', 'global_role' => 'anonymous', ], 'outsider' => [ 'scope' => 'outsider', 'global_role' => 'authenticated', ], 'member' => [ 'scope' => 'insider', 'global_role' => 'authenticated', ], ]; // Update anonymous, outsider and member. foreach ($config_factory->listAll('group.type.') as $group_type_config_name) { $group_type_id = $config_factory->get($group_type_config_name)->get('id'); foreach ($group_role_info as $group_role_suffix => $info) { $group_role_id = "$group_type_id-$group_role_suffix"; // We do not delete the default roles, even if they have no rights. $group_role = $config_factory->getEditable('group.role.' . $group_role_id); $group_role->set('scope', $info['scope']); $group_role->set('global_role', $info['global_role']); // Clear the old keys and save. $group_role->clear('permissions_ui'); $group_role->clear('internal'); $group_role->clear('audience'); $group_role->save(TRUE); } } } /** * Convert user created group roles to new scope and target_role structure. */ function group_update_9206() { $config_factory = \Drupal::configFactory(); foreach ($config_factory->listAll('group.role.') as $config_name) { // Now that we've updated synchronized and default roles, any role that // still has the old properties is a user generated one. So skip the rest. if (empty($config_factory->get($config_name)->get('audience'))) { continue; } // We do not delete the user created roles, even if they have no rights. $group_role = $config_factory->getEditable($config_name); $group_role->set('scope', 'individual'); // Clear the old keys and save. $group_role->clear('permissions_ui'); $group_role->clear('internal'); $group_role->clear('audience'); $group_role->save(TRUE); } }
group.links.task.yml +0 −14 Changes for group.links.task.yml: 0 added lines, 14 removed lines. Original line number Diff line number Diff line Loading @@ -59,20 +59,6 @@ group_type.permissions_form: base_route: 'entity.group_type.edit_form' weight: 15 group_type.permissions_form.basic: title: 'Basic permissions' route_name: 'entity.group_type.permissions_form' base_route: 'entity.group_type.edit_form' parent_id: 'group_type.permissions_form' weight: 0 group_type.permissions_form.outsider: title: 'Advanced outsider permissions' route_name: 'entity.group_type.outsider_permissions_form' base_route: 'entity.group_type.edit_form' parent_id: 'group_type.permissions_form' weight: 5 group_type.roles_list: title: 'Roles' route_name: 'entity.group_role.collection' Loading
group.module +28 −51 Changes for group.module: 28 added lines, 51 removed lines. Original line number Diff line number Diff line Loading @@ -19,7 +19,8 @@ use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Session\AccountInterface; use Drupal\group\Entity\GroupContent; use Drupal\group\QueryAccess\EntityQueryAlter; use Drupal\user\RoleInterface; use Drupal\group\QueryAccess\GroupContentQueryAlter; use Drupal\group\QueryAccess\GroupQueryAlter; use Drupal\views\Plugin\views\query\QueryPluginBase; use Drupal\views\Plugin\views\query\Sql; use Drupal\views\ViewExecutable; Loading Loading @@ -184,11 +185,6 @@ function template_preprocess_group_content(&$variables) { */ function group_rebuild() { _group_relation_type_manager()->installEnforced(); /** @var \Drupal\group\Entity\Storage\GroupRoleStorageInterface $storage */ $storage = \Drupal::entityTypeManager()->getStorage('group_role'); $storage->createInternal(); $storage->createSynchronized(); } /** Loading @@ -198,11 +194,6 @@ function group_modules_installed($modules) { // Only create config objects while config import is not in progress. if (!\Drupal::isConfigSyncing()) { _group_relation_type_manager()->installEnforced(); /** @var \Drupal\group\Entity\Storage\GroupRoleStorageInterface $storage */ $storage = \Drupal::entityTypeManager()->getStorage('group_role'); $storage->createInternal(); $storage->createSynchronized(); } } Loading Loading @@ -245,8 +236,33 @@ function group_query_entity_query_alter(SelectInterface $query) { $entity_type_manager = \Drupal::entityTypeManager(); $entity_type = $entity_type_manager->getDefinition($entity_type_id); // Add specific access checks based on the entity type. Please note that we // first check for the group and group content entity types because we have // full control over those and can therefore optimize the query more. If the // query is for a different entity type, we fall back to the default query // alter. // // PLEASE KEEP IN MIND that this means that a plugin that allows you to nest // groups will have no query access added for nested groups whatsoever. This // is by design as those plugins should opt to use the permission calculator // system, as it's way faster and automatically included in GroupQueryAlter. // // @todo Enforce that plugins may not define entity_access for "group". switch ($entity_type_id) { case 'group': $class_name = GroupQueryAlter::class; break; case 'group_content': $class_name = GroupContentQueryAlter::class; break; default: $class_name = EntityQueryAlter::class; } \Drupal::service('class_resolver') ->getInstanceFromDefinition(EntityQueryAlter::class) ->getInstanceFromDefinition($class_name) ->alter($query, $entity_type); } } Loading Loading @@ -501,33 +517,6 @@ function group_user_delete(EntityInterface $account) { } } /** * Implements hook_ENTITY_TYPE_insert(). */ function group_user_role_insert(RoleInterface $role) { // Only create config objects while config import is not in progress. if (!\Drupal::isConfigSyncing()) { /** @var \Drupal\group\Entity\Storage\GroupRoleStorageInterface $storage */ $storage = \Drupal::entityTypeManager()->getStorage('group_role'); $storage->createSynchronized(NULL, [$role->id()]); } } /** * Implements hook_ENTITY_TYPE_update(). */ function group_user_role_update(RoleInterface $role) { /** @var \Drupal\User\RoleInterface $original */ $original = $role->original; // Update the group roles if the user role label changed. if ($role->label() != $original->label()) { /** @var \Drupal\group\Entity\Storage\GroupRoleStorageInterface $storage */ $storage = \Drupal::entityTypeManager()->getStorage('group_role'); $storage->updateSynchronizedLabels($role); } } /** * Implements hook_form_alter(). */ Loading Loading @@ -706,18 +695,6 @@ function _group_relation_type_manager() { return \Drupal::service('group_relation_type.manager'); } /** * Gets the group role synchronizer service. * * @return \Drupal\group\GroupRoleSynchronizerInterface * The group role synchronizer service. * * @internal Try to properly inject the service when possible. */ function _group_role_synchronizer() { return \Drupal::service('group_role.synchronizer'); } /** * Implements hook_ENTITY_TYPE_presave(). * Loading
group.routing.yml +0 −8 Changes for group.routing.yml: 0 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -54,14 +54,6 @@ entity.group_type.permissions_form: requirements: _permission: 'administer group' entity.group_type.outsider_permissions_form: path: '/admin/group/types/manage/{group_type}/permissions/outsider' defaults: _form: '\Drupal\group\Form\GroupPermissionsOutsiderForm' _title: 'Edit advanced outsider permissions' requirements: _permission: 'administer group' entity.group_type.content_plugins: path: '/admin/group/types/manage/{group_type}/content' defaults: Loading