class GroupMembershipController in Group 7
Controller for group membership entities.
Hierarchy
- class \DrupalDefaultEntityController implements DrupalEntityControllerInterface
- class \EntityAPIController implements EntityAPIControllerRevisionableInterface
- class \GroupMembershipController
- class \EntityAPIController implements EntityAPIControllerRevisionableInterface
Expanded class hierarchy of GroupMembershipController
1 string reference to 'GroupMembershipController'
- group_entity_info in ./
group.entity.inc - Implements hook_entity_info().
File
- classes/
group_membership.controller.inc, line 10 - Defines the Entity API CRUD class for group memberships.
View source
class GroupMembershipController extends EntityAPIController {
/**
* Add group roles to group memberships upon loading.
*
* This will load the memberships' roles before it is passed onto any hooks
* that act upon entity loading.
*/
protected function attachLoad(&$queried_entities, $revision_id = FALSE) {
if ($queried_entities) {
// Gather all loaded memberships' role data.
$query = db_select('group_membership_role', 'gmr')
->fields('gmr', array(
'mid',
'role',
))
->condition('mid', array_keys($queried_entities), 'IN');
// Gather the roles per group membership id.
foreach ($query
->execute() as $record) {
$roles[$record->mid][] = $record->role;
}
// Add the group roles onto the memberships.
foreach ($queried_entities as $mid => $group_membership) {
$group_membership->roles = isset($roles[$mid]) ? $roles[$mid] : array();
}
}
// Invoke the other attachLoad functionality.
parent::attachLoad($queried_entities, $revision_id);
}
/**
* Overridden to take care of saving membership roles.
*
* If this functionality were placed in GroupMembershipController::save(),
* we'd find ourselves in a catch-22:
* - On the one hand we need a membership id to save the roles to
* {group_membership_role}, requiring us to first save new
* GroupMembership entities before saving their roles.
* - On the other hand, saving an entity causes the insert or update hooks
* to be invoked, leaving room for buggy behavior should one try to load
* the recently saved entity again (it gets removed from the cache upon
* being saved to the database).
*
* To solve this without overriding EntityAPIController::save() and without
* having to fiddle with either module or hook weight, we place the code here
* because GroupMembershipController::invoke() is called right after the
* actual insert or update and we are sure to have a membership id already.
*
* @see EntityAPIController::save()
* @see GroupMembershipController::save()
*/
public function invoke($hook, $group_membership) {
if ($hook == 'update' || $hook == 'insert') {
// Below we take care of the 'roles' property that was set on the
// GroupMembership; saving new roles to and removing revoked roles from
// the database. For new GroupMembership entities, we can simply grant
// all of the roles. For existing ones, we need to run some integrity
// checks.
if (!empty($group_membership->is_new)) {
$grant = $group_membership->roles;
}
else {
// Load the original entity to detect changes.
$original = entity_load_unchanged('group_membership', $group_membership->mid);
// Flag new roles for granting.
$grant = array_diff($group_membership->roles, $original->roles);
// Flag old roles for revoking.
$revoke = array_diff($original->roles, $group_membership->roles);
// Inform update hooks if any roles have changed. This is merely a
// helper property so update hooks don't have to check again.
$group_membership->roles_changed = $grant || $revoke;
}
// Grant the roles by inserting them into {group_membership_role}.
if (!empty($grant)) {
$query = db_insert('group_membership_role')
->fields(array(
'mid',
'role',
));
foreach ($grant as $role) {
$query
->values(array(
'mid' => $group_membership->mid,
'role' => $role,
));
}
$query
->execute();
}
// Revoke the roles by deleting them from {group_membership_role}.
if (!empty($revoke)) {
$query = db_delete('group_membership_role')
->condition('mid', $group_membership->mid);
$query
->condition('role', $revoke, 'IN');
$query
->execute();
}
}
// Continue running the actual invoke logic.
parent::invoke($hook, $group_membership);
}
/**
* Delete a group membership.
*/
public function delete($ids, DatabaseTransaction $transaction = NULL) {
if (!empty($ids)) {
// Delete all associated group membership roles.
db_delete('group_membership_role')
->condition('mid', $ids, 'IN')
->execute();
}
parent::delete($ids, $transaction);
}
/**
* Save a group membership.
*
* The saving of roles takes place in GroupMembershipController::invoke().
*
* @see GroupMembershipController::invoke()
*
* @todo Validation of added roles.
*/
public function save($group_membership, DatabaseTransaction $transaction = NULL) {
if (!isset($group_membership->uid) || $group_membership->uid == 0) {
throw new EntityMalformedException(t("Group memberships cannot be created for anonymous users."));
}
// Clean up the 'roles' property to avoid duplicates.
$group_membership->roles = array_unique($group_membership->roles);
return parent::save($group_membership, $transaction);
}
/**
* Create a group membership.
*
* We first set up the values that are specific to the group schema
* but then also run the EntityAPIController counterpart.
*
* @param array $values
* An array of values to set, keyed by property name.
*
* @return GroupMembership
* A new GroupMembership instance.
*/
public function create(array $values = array()) {
// Provide defaults that are needed for the db.
$values += array(
'roles' => array(),
'status' => 'active',
);
return parent::create($values);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DrupalDefaultEntityController:: |
protected | property | Whether this entity type should use the static cache. | |
DrupalDefaultEntityController:: |
protected | property | Static cache of entities, keyed by entity ID. | |
DrupalDefaultEntityController:: |
protected | property | Array of information about the entity. | |
DrupalDefaultEntityController:: |
protected | property | Entity type for this controller instance. | |
DrupalDefaultEntityController:: |
protected | property | Additional arguments to pass to hook_TYPE_load(). | |
DrupalDefaultEntityController:: |
protected | property | Name of the entity's ID field in the entity database table. | |
DrupalDefaultEntityController:: |
protected | property | Name of entity's revision database table field, if it supports revisions. | |
DrupalDefaultEntityController:: |
protected | property | The table that stores revisions, if the entity supports revisions. | |
DrupalDefaultEntityController:: |
protected | function | Gets entities from the static cache. | 1 |
DrupalDefaultEntityController:: |
protected | function | Stores entities in the static entity cache. | |
DrupalDefaultEntityController:: |
protected | function | Ensures integer entity IDs are valid. | |
DrupalDefaultEntityController:: |
protected | function | Callback for array_filter that removes non-integer IDs. | |
EntityAPIController:: |
protected | property | ||
EntityAPIController:: |
protected | property | ||
EntityAPIController:: |
protected | property | ||
EntityAPIController:: |
public | function |
Implements EntityAPIControllerInterface. Overrides EntityAPIControllerInterface:: |
|
EntityAPIController:: |
protected | function |
Overrides DrupalDefaultEntityController::buildQuery(). Overrides DrupalDefaultEntityController:: |
1 |
EntityAPIController:: |
public | function |
Implements EntityAPIControllerRevisionableInterface::deleteRevision(). Overrides EntityAPIControllerRevisionableInterface:: |
|
EntityAPIController:: |
public | function |
Implements EntityAPIControllerInterface. Overrides EntityAPIControllerInterface:: |
1 |
EntityAPIController:: |
public | function |
Implements EntityAPIControllerInterface. Overrides EntityAPIControllerInterface:: |
|
EntityAPIController:: |
public | function |
Overridden. Overrides DrupalDefaultEntityController:: |
1 |
EntityAPIController:: |
public | function | Builds and executes the query for loading. | |
EntityAPIController:: |
protected | function | Renders a single entity property. | |
EntityAPIController:: |
public | function |
Overrides DrupalDefaultEntityController::resetCache(). Overrides DrupalDefaultEntityController:: |
1 |
EntityAPIController:: |
protected | function | Saves an entity revision. | |
EntityAPIController:: |
public | function |
Implements EntityAPIControllerInterface. Overrides EntityAPIControllerInterface:: |
1 |
EntityAPIController:: |
public | function |
Overridden. Overrides DrupalDefaultEntityController:: |
1 |
GroupMembershipController:: |
protected | function |
Add group roles to group memberships upon loading. Overrides DrupalDefaultEntityController:: |
|
GroupMembershipController:: |
public | function |
Create a group membership. Overrides EntityAPIController:: |
|
GroupMembershipController:: |
public | function |
Delete a group membership. Overrides EntityAPIController:: |
|
GroupMembershipController:: |
public | function |
Overridden to take care of saving membership roles. Overrides EntityAPIController:: |
|
GroupMembershipController:: |
public | function |
Save a group membership. Overrides EntityAPIController:: |