### Quick Start Examples Source: https://github.com/project/group/blob/4.0.x/_autodocs/MANIFEST.txt Practical code examples and common workflows for using the Drupal Group module. ```APIDOC ## Quick Start Examples ### Description Offers practical, copy-paste ready code examples demonstrating common workflows and patterns for using the Drupal Group module. ### Content - Practical workflows (load, create, update, delete) - Service injection examples - Query examples and error handling - Configuration management examples ``` -------------------------------- ### Example Route for Creating a Group Source: https://github.com/project/group/blob/4.0.x/_autodocs/ROUTES_AND_CONTROLLERS.md Illustrates the path for creating a new group of a specific type, typically used in a GET request. ```http GET /group/add/company ``` -------------------------------- ### Example: Get Synchronized Global Role Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_TYPE_AND_ROLES.md Demonstrates how to load a group role and retrieve its synchronized global role, then display the global role's label. ```php $role = GroupRole::load('company-admin'); $global = $role->getGlobalRole(); if ($global) { echo "Synchronized with: " . $global->label(); } ``` -------------------------------- ### Complete Configuration Workflow Example Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_TYPE_AND_ROLES.md An example demonstrating a complete workflow for configuring a group type, including loading, checking plugins, managing roles, and setting permissions. ```APIDOC ## Example: Complete Configuration Workflow ```php // Load group type $group_type = GroupType::load('company'); // Check available plugins if ($group_type->hasPlugin('group_node')) { $plugin = $group_type->getPlugin('group_node'); echo "Nodes can be added"; } // Get all roles for this type $roles = $group_type->getRoles(); // Find or create admin role $admin_role = GroupRole::load('company-admin'); if (!$admin_role) { $admin_role = GroupRole::create([ 'id' => 'company-admin', 'label' => 'Administrator', 'group_type' => 'company', ]); } // Configure permissions $admin_role->changePermissions([ 'view group' => TRUE, 'edit group' => TRUE, 'delete group' => TRUE, 'administer members' => TRUE, 'edit group permissions' => TRUE, ])->save(); // Create member role $member_role = GroupRole::create([ 'id' => 'company-member', 'label' => 'Member', 'group_type' => 'company', ]); $member_role->changePermissions([ 'view group' => TRUE, 'edit group' => FALSE, 'leave group' => TRUE, ])->save(); echo "Group type configured with " . count($group_type->getRoles()) . " roles"; ``` ``` -------------------------------- ### Example: Get and Iterate Roles Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Demonstrates how to retrieve a group membership and iterate through its roles, printing each role's label. Ensure the membership object is valid before proceeding. ```php $membership = $group->getMember($user); if ($membership) { $roles = $membership->getRoles(); foreach ($roles as $role_id => $role) { echo $role->label(); } } ``` -------------------------------- ### Get Post-Install Handler for a Group Relation Plugin Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP_TYPES.md Retrieves the post-install handler for a given group relation plugin ID. This handler is executed after a plugin is installed. ```php $manager = \Drupal::service('group_relation_type.manager'); $post_install_handler = $manager->getPostInstallHandler('my_plugin_id'); ``` -------------------------------- ### Discover and Use Group Relationship Plugins Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP_TYPES.md Demonstrates how to retrieve the group relationship type manager, load group types, check for installed plugins, and access plugin handlers like AccessControl and UiTextProvider. It also shows how to find plugins by entity type and iterate through installed plugins. ```php // Get the manager $manager = \Drupal::service('group_relation_type.manager'); // Load a group type $group_type = GroupType::load('company'); // Check if a plugin is installed if ($group_type->hasPlugin('group_node')) { // Get the plugin $plugin = $group_type->getPlugin('group_node'); // Check cardinality echo "Group cardinality: " . $plugin->getGroupCardinality(); echo "Entity cardinality: " . $plugin->getEntityCardinality(); // Get handlers $manager = \Drupal::service('group_relation_type.manager'); $access_handler = $manager->getAccessControlHandler('group_node'); $ui_provider = $manager->getUiTextProvider('group_node'); } // Find what plugins can be used for nodes $node_plugins = $manager->getPluginIdsByEntityTypeId('node'); echo "Plugins for nodes: " . implode(', ', $node_plugins); // Iterate all installed plugins foreach ($group_type->getInstalledPlugins() as $plugin_id => $plugin) { echo $plugin_id . ": can be added to " . $plugin->getGroupCardinality() . " groups"; } // Load all relationship types for a plugin $rel_types = GroupRelationshipType::loadByPluginId('group_node'); foreach ($rel_types as $type) { echo "Type " . $type->id() . " for group type " . $type->getGroupTypeId(); } ``` -------------------------------- ### Get Installed Group Relation Plugins for a Group Type Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP_TYPES.md Retrieves all installed group relation plugins for a given group type. Useful for iterating over available plugins and their labels. ```php $manager = \Drupal::service('group_relation_type.manager'); $group_type = GroupType::load('company'); $plugins = $manager->getInstalled($group_type); foreach ($plugins as $plugin_id => $plugin) { echo $plugin_id . ": " . $plugin->label(); } ``` -------------------------------- ### Get Installed Group Relation Plugins Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_TYPE_AND_ROLES.md Retrieves a collection of all installed group relation plugins for this group type. ```php public function getInstalledPlugins(): GroupRelationCollection ``` ```php $group_type = GroupType::load('company'); $plugins = $group_type->getInstalledPlugins(); foreach ($plugins as $plugin_id => $plugin) { echo $plugin_id . " is installed"; } ``` -------------------------------- ### Check and Get Group Type Plugins Source: https://github.com/project/group/blob/4.0.x/_autodocs/QUICK_START.md Check if a specific plugin is installed for a group type and retrieve plugin instances. This is useful for understanding the capabilities of a group type. ```php $group_type = \Drupal\group\Entity\GroupType::load('company'); // Check if plugin is installed if ($group_type->hasPlugin('group_node')) { echo "Can add nodes"; } // Get plugin $plugin = $group_type->getPlugin('group_node'); echo "Group cardinality: " . $plugin->getGroupCardinality(); echo "Entity cardinality: " . $plugin->getEntityCardinality(); // List all plugins $plugins = $group_type->getInstalledPlugins(); foreach ($plugins as $id => $plugin) { echo $id; } ``` -------------------------------- ### Group Module Code Examples Source: https://github.com/project/group/blob/4.0.x/_autodocs/README.md Information about the types of code examples available for the Group module. ```APIDOC ## Code Examples Included Each document includes multiple complete code examples showing: - Loading and creating entities - Performing operations (add member, add relationship) - Querying and filtering - Service usage - Error handling - Configuration management Examples use: - Drupal service injection patterns - Entity storage API - Query builder syntax - Hook/event implementations - Route generation ``` -------------------------------- ### Example: Check for Specific Permission Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Provides an example of checking if a group member has a particular permission, such as 'edit group'. The code snippet shows a conditional check. ```php $membership = $group->getMember($user); if ($membership && $membership->hasPermission('edit group')) { // Member can edit the group } ``` -------------------------------- ### GroupRelationTypeManagerInterface::getPostInstallHandler() Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP_TYPES.md Fetches the post-install handler for a group relation plugin, which is executed after the plugin is installed. ```APIDOC ## GroupRelationTypeManagerInterface::getPostInstallHandler() ### Description Gets the post-install handler. ### Method `getPostInstallHandler(string $plugin_id): PostInstallInterface` ### Parameters #### Path Parameters - **$plugin_id** (string) - Required - The plugin ID. ### Response #### Success Response (PostInstallInterface) - Returns the post-install handler instance. ``` -------------------------------- ### GroupRelationTypeManagerInterface::getInstalled() Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP_TYPES.md Gets all installed plugins for a specific group type. It returns a collection of group relation plugins that are configured and available for the given group type. ```APIDOC ## GroupRelationTypeManagerInterface::getInstalled() ### Description Gets all installed plugins for a group type. ### Method `getInstalled(GroupTypeInterface $group_type): GroupRelationCollection` ### Parameters #### Path Parameters - **$group_type** (GroupTypeInterface) - Required - The group type to get plugins for. ### Response #### Success Response (GroupRelationCollection) - Returns a collection of installed group relation plugins. ### Example ```php $manager = \Drupal::service('group_relation_type.manager'); $group_type = GroupType::load('company'); $plugins = $manager->getInstalled($group_type); foreach ($plugins as $plugin_id => $plugin) { echo $plugin_id . ": " . $plugin->label(); } ``` ``` -------------------------------- ### Implement hook_modules_installed() Source: https://github.com/project/group/blob/4.0.x/_autodocs/HOOKS_AND_EVENTS.md This hook is invoked after modules are installed. It's useful for setting up group-specific configurations or data when the 'group' module itself or related modules are installed. ```php function my_module_modules_installed(array $modules, bool $is_syncing) { if (in_array('group', $modules)) { // Initialize group data } } ``` -------------------------------- ### Iterating Group Relation Plugins Source: https://github.com/project/group/blob/4.0.x/_autodocs/TYPES_AND_INTERFACES.md Demonstrates how to retrieve and iterate through installed group relation plugins, which implement the GroupRelationInterface. ```php $plugins = $group_type->getInstalledPlugins(); foreach ($plugins as $plugin_id => $plugin) { // Each $plugin implements GroupRelationInterface } ``` -------------------------------- ### Complete Membership Workflow Example Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Demonstrates a full workflow for managing group memberships, including adding members, checking permissions, managing roles, and removing members. ```php // Load a group and user $group = Group::load(1); $user = User::load(2); // Add user as member with initial roles $group->addMember($user, [ 'group_roles' => ['group_type-member'] ]); // Load the membership $membership = GroupMembership::loadSingle($group, $user); // Check and manage roles if ($membership) { // Check if user has permission if ($membership->hasPermission('edit group')) { echo "User can edit"; } // Add another role $membership->addRole('group_type-moderator'); $membership->save(); // Get all roles $roles = $membership->getRoles(); echo count($roles) . " roles"; } // Remove membership $group->removeMember($user); ``` -------------------------------- ### Complete Membership Workflow Example Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Demonstrates a complete workflow for managing group memberships, including adding members, checking permissions, managing roles, and removing memberships. ```APIDOC ## Example: Complete Membership Workflow ```php // Load a group and user $group = Group::load(1); $user = User::load(2); // Add user as member with initial roles $group->addMember($user, [ 'group_roles' => ['group_type-member'] ]); // Load the membership $membership = GroupMembership::loadSingle($group, $user); // Check and manage roles if ($membership) { // Check if user has permission if ($membership->hasPermission('edit group')) { echo "User can edit"; } // Add another role $membership->addRole('group_type-moderator'); $membership->save(); // Get all roles $roles = $membership->getRoles(); echo count($roles) . " roles"; } // Remove membership $group->removeMember($user); ``` ``` -------------------------------- ### Check if Group Relation Plugin is Installed Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_TYPE_AND_ROLES.md Verifies if a specific group relation plugin is installed for this group type. ```php public function hasPlugin(string $plugin_id): bool ``` ```php $group_type = GroupType::load('company'); if ($group_type->hasPlugin('group_node')) { echo "Nodes can be added to this group type"; } ``` -------------------------------- ### Example: Create and Save Group Relationship Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP.md Demonstrates the process of creating a new group relationship for an entity within a group, including setting additional values and saving the relationship. ```php $storage = \Drupal::entityTypeManager()->getStorage('group_relationship'); $node = Node::load(5); $group = Group::load(1); $relationship = $storage->createForEntityInGroup( $node, $group, 'group_node', ['created' => \Drupal::time()->getRequestTime()] ); $storage->save($relationship); ``` -------------------------------- ### Get All Group Permissions Source: https://github.com/project/group/blob/4.0.x/_autodocs/PERMISSIONS_AND_ACCESS.md Retrieves all defined group permissions, optionally including those from relation plugins. Use this to get a comprehensive list of available permissions. ```php public function getPermissions(bool $include_plugins = FALSE): array ``` ```php $handler = \Drupal::service('group.permissions'); $permissions = $handler->getPermissions(); foreach ($permissions as $name => $permission) { echo $name . ": " . $permission['title']; } ``` -------------------------------- ### Example: Add Role to Membership Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Shows how to add a role to a group membership using its ID and then save the changes. This is useful for granting new permissions to a member. ```php $membership = $group->getMember($user); if ($membership) { $membership->addRole('group_type-role_id'); $membership->save(); } ``` -------------------------------- ### GroupTypeInterface::getInstalledPlugins() Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_TYPE_AND_ROLES.md Retrieves a collection of all installed group relation plugins for this group type. ```APIDOC ## GroupTypeInterface::getInstalledPlugins() ### Description Returns the installed group relations (plugins) for this group type. ### Method ```php public function getInstalledPlugins(): GroupRelationCollection ``` ### Returns `GroupRelationCollection` - Plugin collection ### Example ```php $group_type = GroupType::load('company'); $plugins = $group_type->getInstalledPlugins(); foreach ($plugins as $plugin_id => $plugin) { echo $plugin_id . " is installed"; } ``` ``` -------------------------------- ### Get Group Roles and Permissions Source: https://github.com/project/group/blob/4.0.x/_autodocs/QUICK_START.md Retrieve all roles for a given group type and list their associated permissions. ```php $group_type = \Drupal\group\Entity\GroupType::load('company'); $roles = $group_type->getRoles(); foreach ($roles as $role_id => $role) { echo $role->label() . " - "; echo implode(', ', $role->getPermissions()); } ``` -------------------------------- ### Module Integration in YAML Source: https://github.com/project/group/blob/4.0.x/_autodocs/QUICK_START.md Define a service in your module's services.yml file. This example shows how to register a custom group handler with its dependencies and tags. ```yaml my_module.services.yml: services: my_module.group_handler: class: Drupal\my_module\GroupHandler arguments: - '@group_permission.checker' - '@entity_type.manager' tags: - { name: 'event_subscriber' } ``` -------------------------------- ### Get All Permissions for a Role Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_TYPE_AND_ROLES.md Retrieves all permission names assigned to a specific role. Useful for checking the current permission set. ```php public function getPermissions(): string[] ``` ```php $role = GroupRole::load('company-admin'); $permissions = $role->getPermissions(); if (in_array('edit group', $permissions)) { echo "Role can edit group"; } ``` -------------------------------- ### Configure Group Type Content Plugins Source: https://github.com/project/group/blob/4.0.x/_autodocs/ROUTES_AND_CONTROLLERS.md Displays a table of installed and available content plugins for a group type, allowing configuration. This is an administrative endpoint. ```APIDOC ## GET /admin/group/types/manage/{group_type}/content ### Description Configure which content plugins are installed. ### Method GET ### Endpoint /admin/group/types/manage/{group_type}/content ### Parameters #### Path Parameters - **group_type** (entity) - Required - Group type ### Controller GroupTypeController::content() ### Requirements - _permission: 'administer group' ### Returns Table of installed/available content plugins ``` -------------------------------- ### Module Integration in Routes YAML Source: https://github.com/project/group/blob/4.0.x/_autodocs/QUICK_START.md Define a custom route in your module's routing.yml file. This example demonstrates setting a path, default controller, and access requirements using group permissions. ```yaml my_module.group_custom: path: '/group/{group}/custom' defaults: _controller: 'Drupal\my_module\Controller\CustomController::view' requirements: _group_permission: 'view group' ``` -------------------------------- ### Get Group Permission Calculator Service Source: https://github.com/project/group/blob/4.0.x/_autodocs/PERMISSIONS_AND_ACCESS.md Retrieves the service responsible for calculating group permissions based on Flexible Permissions policies. ```php $calculator = \Drupal::service('group_permission.calculator'); ``` -------------------------------- ### Group Relationship Type Routes Source: https://github.com/project/group/blob/4.0.x/_autodocs/ROUTES_AND_CONTROLLERS.md Routes for managing group relationship types, including installing, configuring, and uninstalling content plugins. ```APIDOC ## entity.group_relationship_type.add-form ### Description Install a content plugin on a group type. ### Method GET, POST ### Endpoint /admin/group/content/install/{group_type}/{plugin_id} ### Parameters - `{group_type}` — Group type ID (string parameter) - `{plugin_id}` — Relation plugin ID (string parameter) ### Requirements - `_permission`: 'administer group' ``` ```APIDOC ## entity.group_relationship_type.edit-form ### Description Configure an installed content plugin. ### Method GET, POST ### Endpoint /admin/group/content/manage/{group_relationship_type} ### Parameters - `{group_relationship_type}` — Relationship type entity (auto-loaded) ### Requirements - `_permission`: 'administer group' ``` ```APIDOC ## entity.group_relationship_type.delete-form ### Description Uninstall a content plugin from a group type. ### Method GET, POST ### Endpoint /admin/group/content/manage/{group_relationship_type}/uninstall ### Requirements - `_permission`: 'administer group' ``` -------------------------------- ### Handle Invalid Plugin in PHP Source: https://github.com/project/group/blob/4.0.x/_autodocs/QUICK_START.md Verify if a group type has a specific plugin installed before attempting to retrieve it. Throws an InvalidArgumentException if the plugin is not found. ```php $group_type = GroupType::load('company'); if (!$group_type->hasPlugin('group_node')) { throw new \InvalidArgumentException('Plugin not installed'); } $plugin = $group_type->getPlugin('group_node'); ``` -------------------------------- ### GroupRelationTypeManagerInterface::getInstalledIds() Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP_TYPES.md Gets the IDs of all installed group relation plugins for a specific group type. ```APIDOC ## GroupRelationTypeManagerInterface::getInstalledIds() ### Description Gets installed plugin IDs for a group type. ### Method `getInstalledIds(GroupTypeInterface $group_type): string[]` ### Parameters #### Path Parameters - **$group_type** (GroupTypeInterface) - Required - The group type to get plugin IDs for. ### Response #### Success Response (string[]) - Returns an array of plugin IDs. ``` -------------------------------- ### Get Group Relationship Storage Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP.md Retrieves the storage handler for group relationship entities. This is a common starting point for using the interface methods. ```php /** @var \Drupal\group\Entity\Storage\GroupRelationshipStorage $storage */ $storage = \Drupal::entityTypeManager()->getStorage('group_relationship'); ``` -------------------------------- ### Get All Group Memberships Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_ENTITY.md Retrieves all membership entities for a group, optionally filtered by a list of roles. An empty role list returns all memberships. ```php public function getMembers(array $roles = []): GroupMembershipInterface[] ``` ```php $group = \Drupal::entityTypeManager()->getStorage('group')->load(1); // Get all members $all_members = $group->getMembers(); // Get members with specific roles $admins = $group->getMembers(['admin_role_id']); ``` -------------------------------- ### Complete Group Type Configuration Workflow Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_TYPE_AND_ROLES.md Demonstrates a full workflow for configuring a group type, including loading, checking plugins, creating and configuring roles with specific permissions, and saving changes. ```php // Load group type $group_type = GroupType::load('company'); // Check available plugins if ($group_type->hasPlugin('group_node')) { $plugin = $group_type->getPlugin('group_node'); echo "Nodes can be added"; } // Get all roles for this type $roles = $group_type->getRoles(); // Find or create admin role $admin_role = GroupRole::load('company-admin'); if (!$admin_role) { $admin_role = GroupRole::create([ 'id' => 'company-admin', 'label' => 'Administrator', 'group_type' => 'company', ]); } // Configure permissions $admin_role->changePermissions([ 'view group' => TRUE, 'edit group' => TRUE, 'delete group' => TRUE, 'administer members' => TRUE, 'edit group permissions' => TRUE, ])->save(); // Create member role $member_role = GroupRole::create([ 'id' => 'company-member', 'label' => 'Member', 'group_type' => 'company', ]); $member_role->changePermissions([ 'view group' => TRUE, 'edit group' => FALSE, 'leave group' => TRUE, ])->save(); echo "Group type configured with " . count($group_type->getRoles()) . " roles"; ``` -------------------------------- ### Load Group Relationships by Group Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP.md Retrieves all relationships associated with a specific group. Optionally filter by a plugin ID to get relationships of a particular type. ```php public function loadByGroup( GroupInterface $group, ?string $plugin_id = NULL ): GroupRelationshipInterface[] ``` -------------------------------- ### Implement hook_help() Source: https://github.com/project/group/blob/4.0.x/_autodocs/HOOKS_AND_EVENTS.md Provides help text for specific admin pages, particularly for group-related routes. Customize the displayed help content for different administrative interfaces. ```php function my_module_help($route_name, $route_match) { switch ($route_name) { case 'entity.group.canonical': return '

This is a group.

'; } return ''; } ``` -------------------------------- ### Get Group Cardinality - PHP Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP_TYPES.md Retrieves the maximum number of groups an entity can be associated with. Use -1 for unlimited. This example shows how to load a group type and its plugin to check this value. ```php public function getGroupCardinality(): int ``` ```php $group_type = GroupType::load('company'); $plugin = $group_type->getPlugin('group_node'); echo "Each node can be in " . $plugin->getGroupCardinality() . " groups"; // Output: "Each node can be in -1 groups" (unlimited) ``` -------------------------------- ### Join Group Source: https://github.com/project/group/blob/4.0.x/_autodocs/ROUTES_AND_CONTROLLERS.md Allows a user to join a group. This endpoint can be accessed via GET or POST. It requires the user not to be a member of the group and to have the 'join group' permission. ```APIDOC ## POST /group/{group}/join ### Description Page to join a group. ### Method GET, POST ### Endpoint /group/{group}/join ### Parameters #### Path Parameters - **group** (entity) - Required - Group entity (auto-loaded) ### Returns Confirmation form or redirect after joining ### Request Example ``` POST /group/1/join ``` ``` -------------------------------- ### Get Specific Group Relation Plugin Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_TYPE_AND_ROLES.md Retrieves an installed group relation plugin instance for this group type. It is recommended to call `hasPlugin()` first to ensure the plugin exists and avoid exceptions. ```php public function getPlugin(string $plugin_id): GroupRelationInterface ``` ```php $group_type = GroupType::load('company'); if ($group_type->hasPlugin('group_node')) { $plugin = $group_type->getPlugin('group_node'); echo "Max groups per node: " . $plugin->getGroupCardinality(); } ``` -------------------------------- ### Cache Group Data in PHP Source: https://github.com/project/group/blob/4.0.x/_autodocs/QUICK_START.md Implement caching for expensive group data operations to improve performance. This example uses Drupal's default cache backend and sets data permanently. ```php $cid = 'my_module:group_' . $group->id(); $cache = \Drupal::cache('default'); if ($cached = $cache->get($cid)) { return $cached->data; } $data = expensive_operation($group); $cache->set($cid, $data, \Drupal\Core\Cache\Cache::PERMANENT); ``` -------------------------------- ### Get Entity Cardinality - PHP Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP_TYPES.md Retrieves the maximum number of times a specific entity can be added to a single group. Use -1 for unlimited. This example demonstrates checking this constraint via a group type's plugin. ```php public function getEntityCardinality(): int ``` ```php $plugin = $group_type->getPlugin('group_node'); echo "Each node can be added " . $plugin->getEntityCardinality() . " times"; // Output: "Each node can be added 1 times" (once per group) ``` -------------------------------- ### Storage and Queries Source: https://github.com/project/group/blob/4.0.x/_autodocs/MANIFEST.txt Information on storage handlers, entity loading, querying, and caching strategies. ```APIDOC ## Storage and Queries ### Description Details the storage handlers, entity loading and querying mechanisms, and caching strategies employed by the Group module. ### Components - Storage handlers and interfaces - Entity loading and querying - Query access alteration - Caching strategies and performance ``` -------------------------------- ### Avoid N+1 Queries in Loops Source: https://github.com/project/group/blob/4.0.x/_autodocs/STORAGE_AND_QUERIES.md Demonstrates the difference between inefficiently loading related entities within a loop and efficiently batch loading them. ```php // Bad: Loads group for each relationship foreach ($relationships as $rel) { $group = $rel->getGroup(); // Separate query per relationship } // Good: Batch load relationships with groups pre-loaded $relationships = $storage->loadByGroup($group); foreach ($relationships as $rel) { $group = $rel->getGroup(); // Already loaded } ``` -------------------------------- ### Example: Remove Role from Membership Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Illustrates how to remove a role from a group membership by its ID and persist the change by saving the membership. This is used to revoke a member's role. ```php $membership = $group->getMember($user); if ($membership) { $membership->removeRole('group_type-role_id'); $membership->save(); } ``` -------------------------------- ### Complete Permission Check Workflow in PHP Source: https://github.com/project/group/blob/4.0.x/_autodocs/PERMISSIONS_AND_ACCESS.md Demonstrates various methods for checking user permissions against groups, including basic checks, edit permissions, and role-based access. It also shows how to retrieve all defined permissions for a group type and perform a full access control check. ```php // Get the permission checker $checker = \Drupal::service('group_permission.checker'); $handler = \Drupal::service('group.permissions'); // Load entities $user = User::load(2); $group = Group::load(1); // Check basic permissions if ($checker->hasPermissionInGroup('view group', $user, $group)) { echo "User can view group"; } // Check edit permission if ($checker->hasPermissionInGroup('edit group', $user, $group)) { echo "User can edit group"; } // Get defined permissions for group type $group_type = $group->getGroupType(); $permissions = $handler->getPermissionsByGroupType($group_type); // Display available permissions foreach ($permissions as $perm_name => $perm) { echo $perm['title'] . ": " . $perm['description']; } // Check via Group entity method if ($group->hasPermission('administer members', $user)) { echo "User can manage members"; } // Load user's membership and check role-based access $membership = $group->getMember($user); if ($membership && $membership->hasPermission('edit group')) { echo "Member has edit permission"; } // Use with access control check if ($group->access('edit', $user)) { // Full access control check (includes node access, etc.) echo "User has all required access"; } ``` -------------------------------- ### Plugin Configuration Structure Source: https://github.com/project/group/blob/4.0.x/_autodocs/TYPES_AND_INTERFACES.md Outlines the configuration array structure for a plugin, including its ID, label, entity type, and associated handlers. ```php [ 'id' => 'plugin_id', 'label' => 'Plugin Label', 'entity_type_id' => 'node', 'enforced' => FALSE, 'handlers' => [ 'access_control' => 'GroupMembershipAccessControl', 'entity_reference' => 'GroupMembershipEntityReference', ], ] ``` -------------------------------- ### Complete Group Relationship Workflow Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP.md Demonstrates how to add, load, inspect, and remove group relationships. It shows both the recommended method via the Group entity and direct interaction with the storage. Use this for full lifecycle management of relationships. ```php // Load or create entities $group = Group::load(1); $node = Node::load(5); // Add relationship via Group entity (recommended) $relationship = $group->addRelationship($node, 'group_node', [ 'created' => \Drupal::time()->getRequestTime() ]); // Or directly via storage $storage = \Drupal::entityTypeManager()->getStorage('group_relationship'); $relationship = $storage->createForEntityInGroup($node, $group, 'group_node'); $storage->save($relationship); // Load and inspect $loaded = GroupRelationship::load($relationship->id()); echo "Entity: " . $loaded->getEntity()->label(); echo "Group: " . $loaded->getGroup()->label(); echo "Type: " . $loaded->getPluginId(); // Find by entity $all_relationships = GroupRelationship::loadByEntity($node); foreach ($all_relationships as $rel) { echo "In group: " . $rel->getGroup()->label(); } // Remove $relationship->delete(); ``` -------------------------------- ### Accessing Relationships via Group Entity Source: https://github.com/project/group/blob/4.0.x/_autodocs/STORAGE_AND_QUERIES.md Load a group and retrieve its relationships, including filtering by type or accessing related entities directly. Also shows how to get relationships associated with a specific entity. ```php $group = Group::load(1); // Get all relationships $relationships = $group->getRelationships(); // Get relationships of specific type $memberships = $group->getRelationships('group_membership'); // Get the actual entities (not relationships) $members = $group->getRelatedEntities('group_membership'); // Get relationships for a specific entity $node = Node::load(5); $node_rels = $group->getRelationshipsByEntity($node); ``` -------------------------------- ### Routes and Controllers Source: https://github.com/project/group/blob/4.0.x/_autodocs/MANIFEST.txt Overview of all HTTP routes, including CRUD operations, join/leave actions, and administrative endpoints. ```APIDOC ## Routes and Controllers ### Description Documents all HTTP routes provided by the Group module, covering CRUD operations, join/leave actions, and administrative interfaces. ### Details - All HTTP routes (CRUD, join/leave, admin) - Route parameters and access requirements - Entity parameter conversion - Reverse route generation ``` -------------------------------- ### Types and Interfaces Source: https://github.com/project/group/blob/4.0.x/_autodocs/MANIFEST.txt Reference for all entity interfaces, plugin system interfaces, and handler interfaces. ```APIDOC ## Types and Interfaces ### Description Provides a reference for all entity interfaces, plugin system interfaces, handler interfaces, and configuration array structures used within the Group module. ### Components - All entity interfaces - Plugin system interfaces - Handler interfaces and collection types - Configuration array structures ``` -------------------------------- ### Get Relation Type - PHP Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP_TYPES.md Retrieves the full relation type definition object. ```php public function getRelationType(): GroupRelationTypeInterface ``` -------------------------------- ### Hooks and Events Source: https://github.com/project/group/blob/4.0.x/_autodocs/MANIFEST.txt Reference for core and custom hooks, event subscribers, and implementation patterns. ```APIDOC ## Hooks and Events ### Description Documents the core hooks (e.g., rebuild, modules_installed) and custom hooks (e.g., hook_group_operations_alter()), along with event subscribers and implementation patterns. ### Covered Hooks - Core hooks: rebuild, modules_installed, help - Custom hooks: hook_group_operations_alter() - Event subscribers and implementation patterns ``` -------------------------------- ### GroupTypeInterface::hasPlugin() Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_TYPE_AND_ROLES.md Checks if a specific group relation plugin is installed and available for this group type. ```APIDOC ## GroupTypeInterface::hasPlugin() ### Description Checks whether a specific group relation plugin is installed. ### Method ```php public function hasPlugin(string $plugin_id): bool ``` ### Parameters #### Path Parameters - **$plugin_id** (string) - Required - The plugin ID to check ### Returns `bool` - TRUE if installed ### Example ```php $group_type = GroupType::load('company'); if ($group_type->hasPlugin('group_node')) { echo "Nodes can be added to this group type"; } ``` ``` -------------------------------- ### Get Creation Timestamp Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Returns the Unix timestamp when the group membership was created. Inherited from GroupRelationshipInterface. ```php public function getCreatedTime(): int ``` -------------------------------- ### Use Appropriate Entity Load Methods Source: https://github.com/project/group/blob/4.0.x/_autodocs/STORAGE_AND_QUERIES.md Select the correct method for loading entities based on whether you need a single entity, multiple entities by a specific field, or a complex filtered set. ```php // Load single: use get() $rel = $storage->load(1); // Efficient // Load multiple: use loadByGroup() $rels = $storage->loadByGroup($group); // Optimized query // Complex filter: use getQuery() $query = $storage->getQuery() ->condition('group_id', 1) ->range(0, 50) ->execute(); ``` -------------------------------- ### Get User ID Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Returns the ID of the user associated with this membership. This method is inherited from GroupRelationshipInterface. ```php public function getEntityId(): int|string ``` -------------------------------- ### Get Group ID Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Returns the integer ID of the group associated with this membership. Inherited from GroupRelationshipInterface. ```php public function getGroupId(): int ``` -------------------------------- ### Get Group Entity Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Returns the group entity this membership belongs to. This method is inherited from GroupRelationshipInterface. ```php public function getGroup(): GroupInterface ``` -------------------------------- ### Create a Group Source: https://github.com/project/group/blob/4.0.x/_autodocs/QUICK_START.md Create a new group entity with specified type, label, and creator. The group must be saved after creation. ```php $group = \Drupal::entityTypeManager()\n ->getStorage('group')\n ->create([ 'type' => 'company', // group type 'label' => 'ACME Corp', 'uid' => 1, // creator ]); $group->save(); ``` -------------------------------- ### Accessing Group Permission Services Source: https://github.com/project/group/blob/4.0.x/_autodocs/PERMISSIONS_AND_ACCESS.md Demonstrates how to retrieve the core services for group permission management via the Drupal service container. ```php $calculator = \Drupal::service('group_permission.calculator'); $checker = \Drupal::service('group_permission.checker'); $handler = \Drupal::service('group.permissions'); ``` -------------------------------- ### GroupRelationTypeManagerInterface::getAllInstalledIds() Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP_TYPES.md Retrieves the IDs of all installed group relation plugins across all available group types. ```APIDOC ## GroupRelationTypeManagerInterface::getAllInstalledIds() ### Description Gets all installed plugin IDs across all group types. ### Method `getAllInstalledIds(): string[]` ### Response #### Success Response (string[]) - Returns an array of all installed plugin IDs. ``` -------------------------------- ### Get Group Type - PHP Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP_TYPES.md Retrieves the group type object this plugin is configured for, or null if not applicable. ```php public function getGroupType(): GroupTypeInterface|null ``` -------------------------------- ### Add User to a Group Source: https://github.com/project/group/blob/4.0.x/_autodocs/INDEX.md Loads a group and a user, then adds the user to the group with specified roles. Ensure both group and user entities exist before execution. ```php $group = Group::load($id); $user = User::load($uid); $group->addMember($user, ['group_roles' => ['role_id']]); ``` -------------------------------- ### Get Group Type ID - PHP Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP_TYPES.md Retrieves the unique identifier for the group type this plugin is configured for. ```php public function getGroupTypeId(): string|null ``` -------------------------------- ### Get Relation Type ID - PHP Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP_TYPES.md Retrieves the unique identifier for the relation type associated with this plugin. ```php public function getRelationTypeId(): string ``` -------------------------------- ### Get Group Relation Plugin Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP.md Retrieves the group relation plugin instance that handles this specific relationship. ```php public function getPlugin(): GroupRelationInterface ``` -------------------------------- ### Permissions and Access Source: https://github.com/project/group/blob/4.0.x/_autodocs/MANIFEST.txt Documentation for the permission checking service, access control, and route requirements. ```APIDOC ## Permissions and Access ### Description Details the permission checking service (`group_permission.checker`), permission handlers, and route access requirements. ### Components - Permission checking service (`group_permission.checker`) - Permission handler and calculator - Route access requirements and cache contexts - Access policies and permission definitions ``` -------------------------------- ### Get Plugin ID Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Returns the plugin ID, which is always 'group_membership' for group memberships. Inherited from GroupRelationshipInterface. ```php public function getPluginId(): string ``` -------------------------------- ### Get User Entity Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Returns the user entity associated with this group membership. This method is inherited from GroupRelationshipInterface. ```php public function getEntity(): UserInterface ``` -------------------------------- ### Create New Group Role Source: https://github.com/project/group/blob/4.0.x/_autodocs/QUICK_START.md Create a new role for a group type, assign a scope, and grant initial permissions. ```php $role = \Drupal\group\Entity\GroupRole::create([ 'id' => 'company-moderator', 'label' => 'Moderator', 'group_type' => 'company', 'scope' => 'individual', ]); $role->grantPermissions([ 'view group', 'administer members', ])->save(); ``` -------------------------------- ### Get Group Type ID Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Returns the string ID of the group type for this membership. Inherited from GroupRelationshipInterface. ```php public function getGroupTypeId(): string ``` -------------------------------- ### Get Group Type Entity Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Retrieves the group type entity for this membership. This method is inherited from GroupRelationshipInterface. ```php public function getGroupType(): GroupTypeInterface ``` -------------------------------- ### Defining Custom Permissions in YAML Source: https://github.com/project/group/blob/4.0.x/_autodocs/PERMISSIONS_AND_ACCESS.md Shows the format for defining custom permissions in a `group.permissions.yml` file. This includes the permission title, description, and an option to restrict access. ```yaml view group: title: View group description: View a group edit group: title: Edit group description: Edit a group restrict access: true ``` -------------------------------- ### GroupTypeInterface::getPlugin() Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_TYPE_AND_ROLES.md Retrieves an installed group relation plugin instance for this group type, identified by its plugin ID. ```APIDOC ## GroupTypeInterface::getPlugin() ### Description Gets an installed group relation plugin for this type. ### Method ```php public function getPlugin(string $plugin_id): GroupRelationInterface ``` ### Parameters #### Path Parameters - **$plugin_id** (string) - Required - The plugin ID to retrieve ### Returns `GroupRelationInterface` - The plugin instance ### Throws Exception if plugin is not installed ### Notes - Always call `hasPlugin()` first to avoid errors - Returns the configured plugin instance for this group type ### Example ```php $group_type = GroupType::load('company'); if ($group_type->hasPlugin('group_node')) { $plugin = $group_type->getPlugin('group_node'); echo "Max groups per node: " . $plugin->getGroupCardinality(); } ``` ``` -------------------------------- ### Retrieve Available Permissions Source: https://github.com/project/group/blob/4.0.x/_autodocs/TYPES_AND_INTERFACES.md Retrieves a list of all available permissions, optionally including those defined by plugins. Useful for permission management UIs. ```php public function getPermissions(bool $include_plugins = FALSE): array ``` -------------------------------- ### Get Role Scope Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_TYPE_AND_ROLES.md Retrieves the scope of the group role, indicating whether it is individual, for outsiders, or for anonymous users. ```php public function getScope(): string ``` -------------------------------- ### Inject Group Services into a Custom Class Source: https://github.com/project/group/blob/4.0.x/_autodocs/QUICK_START.md Demonstrates how to inject Group module services, such as the permission checker and entity type manager, into a custom service class using constructor injection. ```php class MyService { public function __construct( protected GroupPermissionCheckerInterface $checker, protected EntityTypeManager $entityTypeManager, ) {} public function checkAccess(GroupInterface $group, AccountInterface $account) { return $this->checker->hasPermissionInGroup( 'view group', $account, $group ); } } ``` ```yaml my_module.my_service: class: Drupal\my_module\MyService arguments: - '@group_permission.checker' - '@entity_type.manager' ``` -------------------------------- ### Get Group Entity Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP.md Retrieves the group entity to which this relationship belongs. Use this to access the group's properties. ```php public function getGroup(): GroupInterface ``` ```php $relationship = GroupRelationship::load(1); $group = $relationship->getGroup(); echo $group->label(); ``` -------------------------------- ### Group Module Settings Route Source: https://github.com/project/group/blob/4.0.x/_autodocs/ROUTES_AND_CONTROLLERS.md Defines the route for global Group module settings. Requires administrator permission. ```yaml group.settings: path: '/admin/group/settings' defaults: _form: 'Drupal\group\Form\GroupSettingsForm' requirements: _permission: 'administer group' ``` -------------------------------- ### Get Group Creation Time Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_ENTITY.md Retrieves the creation timestamp of a group entity. Use this to display when a group was created. ```php public function getCreatedTime(): int ``` ```php $group = \Drupal::entityTypeManager()->getStorage('group')->load(1); $created = $group->getCreatedTime(); echo date('Y-m-d H:i:s', $created); ``` -------------------------------- ### loadSingle() Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_MEMBERSHIP.md Loads a single group membership for a user in a group. Returns the membership object if found, otherwise returns false. ```APIDOC ## loadSingle() ### Description Loads a single group membership for a user in a group. ### Method `public static function loadSingle(GroupInterface $group, AccountInterface $account): GroupMembershipInterface|false` ### Parameters #### Path Parameters - **$group** (`GroupInterface`) - Required - The group to load the membership from - **$account** (`AccountInterface`) - Required - The user to load the membership for ### Response #### Success Response - **GroupMembershipInterface** - The loaded membership object. #### Failure Response - **false** - If no membership is found. ### Example ```php $group = Group::load(1); $user = User::load(2); $membership = GroupMembership::loadSingle($group, $user); if ($membership) { echo "User is a member"; } ``` ``` -------------------------------- ### Get Permission Provider for a Group Relation Plugin Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP_TYPES.md Retrieves the permission provider for a specified group relation plugin ID. ```php $manager = \Drupal::service('group_relation_type.manager'); $permission_provider = $manager->getPermissionProvider('my_plugin_id'); ``` -------------------------------- ### Check Role Permissions Source: https://github.com/project/group/blob/4.0.x/_autodocs/QUICK_START.md Verify if a specific role has a particular permission or retrieve all permissions assigned to it. ```php $role = \Drupal\group\Entity\GroupRole::load('company-admin'); if ($role->hasPermission('edit group')) { echo "Role can edit"; } $perms = $role->getPermissions(); ``` -------------------------------- ### Get Role Weight Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_TYPE_AND_ROLES.md Returns the integer weight of a role, used for sorting. Lower values indicate higher priority. ```php public function getWeight(): int ``` -------------------------------- ### Module Settings Source: https://github.com/project/group/blob/4.0.x/_autodocs/ROUTES_AND_CONTROLLERS.md Provides access to the global settings form for the Group module. ```APIDOC ## Module Settings ### group.settings Global Group module settings. **Path:** `/admin/group/settings` **Method:** GET, POST **Form:** `GroupSettingsForm` **Requirements:** - `_permission`: 'administer group' **Returns:** Form for module-level configuration ``` -------------------------------- ### Load Relationships by Plugin ID Source: https://github.com/project/group/blob/4.0.x/_autodocs/STORAGE_AND_QUERIES.md Retrieves all relationships of a specific plugin type. This is useful for fetching all instances of a particular kind of relationship, like all memberships. ```php public function loadByPluginId(string $plugin_id): GroupRelationshipInterface[] ``` ```php $storage = \Drupal::entityTypeManager() ->getStorage('group_relationship'); // Get all memberships in the system $memberships = $storage->loadByPluginId('group_membership'); ``` -------------------------------- ### Get Related Entity Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP.md Retrieves the entity that has been added to the group via this relationship. Use this to access the properties of the related entity. ```php public function getEntity(): EntityInterface ``` ```php $relationship = GroupRelationship::load(1); $entity = $relationship->getEntity(); echo $entity->getEntityTypeId(); // "node", "user", etc. ``` -------------------------------- ### Parameter Conversion Source: https://github.com/project/group/blob/4.0.x/_autodocs/ROUTES_AND_CONTROLLERS.md Explains how route parameters are automatically converted to entities. ```APIDOC ## Parameter Conversion Entity parameters are automatically loaded: | Parameter | Converted To | Storage | |-----------|--------------|---------| | `{group}` | `Group` entity | `group_storage` | | `{group_type}` | `GroupType` entity | `group_type_storage` | | `{group_role}` | `GroupRole` entity | `group_role_storage` | | `{group_relationship_type}` | `GroupRelationshipType` entity | `group_relationship_type_storage` | String parameters (e.g., `{plugin_id}`) are passed as-is. ``` -------------------------------- ### Get Relationship Type Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_RELATIONSHIP.md Retrieves the relationship type entity associated with a group relationship. Use this to access the configuration for the relationship. ```php public function getRelationshipType(): GroupRelationshipTypeInterface ``` ```php $relationship = GroupRelationship::load(1); $type = $relationship->getRelationshipType(); echo $type->label(); ``` -------------------------------- ### Get Group Permissions Hash Generator Service Source: https://github.com/project/group/blob/4.0.x/_autodocs/PERMISSIONS_AND_ACCESS.md Retrieves the service responsible for generating permission hashes for cache contexts. ```php $generator = \Drupal::service('group_permission.hash_generator'); ``` -------------------------------- ### Batch Load Related Data in PHP Source: https://github.com/project/group/blob/4.0.x/_autodocs/QUICK_START.md Avoid N+1 query problems by loading multiple group types at once using loadMultiple. This optimizes fetching related data for several groups. ```php $groups = Group::loadMultiple([1, 2, 3]); // Pre-load types at once (avoids N+1) foreach ($groups as $group) { $type = $group->getGroupType(); } ``` -------------------------------- ### Get Group Relationships by Entity Source: https://github.com/project/group/blob/4.0.x/_autodocs/GROUP_ENTITY.md Finds all relationship entities for a specific entity within a group. This can be filtered by a plugin ID. ```php public function getRelationshipsByEntity( EntityInterface $entity, ?string $plugin_id = NULL ): GroupRelationshipInterface[] ``` ```php $group = \Drupal::entityTypeManager()->getStorage('group')->load(1); $node = \Drupal::entityTypeManager()->getStorage('node')->load(5); $relationships = $group->getRelationshipsByEntity($node); if (!empty($relationships)) { echo "Node is in group"; } ``` -------------------------------- ### Accessing Relationships via Storage Source: https://github.com/project/group/blob/4.0.x/_autodocs/STORAGE_AND_QUERIES.md Use the entity storage to load group relationships by ID, by group, by entity, or by a combination of entity and group. Requires loading the storage service first. ```php $storage = \Drupal::entityTypeManager() ->getStorage('group_relationship'); // Load a relationship $rel = $storage->load(1); // Load multiple by group $rels = $storage->loadByGroup($group, 'group_membership'); // Load by entity $rels = $storage->loadByEntity($node); // Load by entity and group $rels = $storage->loadByEntityAndGroup($node, $group); ```