Bundle classes in core have a limitation of one class per bundle. This makes sense for most of core, but Group spawns a GroupRelationshipType for each combination of GroupType with a specific plugin. So if you have 5 group types, you have 5 different bundles representing the concept of a group membership.
To combat the poor DX, we've introduced a concept of a "shared bundle class". For all intents and purposes it acts like a regular bundle class, but it will work for all bundles of a specific plugin. Keep in mind that if you have any regular bundle class defined, those will still take precedence.
Order of priority (for GroupRelationship entities):
- Specific bundle class
- Shared bundle class
- Regular entity class
How to create a shared bundle class
Like all bundle classes, you must extend the original entity class (GroupRelationship). However, because shared bundle classes don't work out of the box, we've taken care of some stuff for you in \Drupal\group\Entity\SharedBundleClassBase, so it's strongly advised to extend that one instead.
Then, put all of your plugin-specific logic in an interface and trait and use your trait in your shared bundle class. This allows people who want to make a specific bundle class to still have the option of implementing your interface and logic without having to extend your shared bundle class:
/**
* Shared bundle class for a GroupRelationship entity representing a membership.
*/
class GroupMembership extends SharedBundleClassBase implements GroupMembershipInterface {
use GroupMembershipTrait; // <-- THIS CONTAINS THE ACTUAL LOGIC
}
/**
* Provides an interface defining a Group membership bundle entity.
*
* @ingroup group
*/
interface GroupMembershipInterface extends GroupRelationshipInterface {
/**
* Returns the group roles for the membership.
*
* ...
*/
public function getRoles($include_synchronized = TRUE);
Finally, declare the shared bundle class in your (or someone else's) plugin's annotation using the shared_bundle_class key:
/**
* Provides a group relation for users as members.
*
* @GroupRelationType(
* id = "group_membership",
* label = @Translation("Group membership"),
* description = @Translation("Adds users to groups as members."),
* entity_type_id = "user",
* shared_bundle_class = "Drupal\group\Entity\GroupMembership",
* pretty_path_key = "member",
* reference_label = @Translation("User"),
* reference_description = @Translation("The user you want to make a member"),
* enforced = TRUE,
* admin_permission = "administer members"
* )
*/
class GroupMembership extends GroupRelationBase {