Commit 76f211a2 authored by ezra-g's avatar ezra-g Committed by amitaibu

Issue #2169099 by Amitaibu, ezra-g: Avoid unnecessary entity loads in group reference fields.

parent a08860a8
......@@ -362,30 +362,13 @@ function og_get_field_og_membership_properties($entity, array $options, $name, $
$field_name = substr($name, 0, $remove_char);
$field_name = $args[0];
$state = count($args) == 2 ? FALSE : $args[2];
list($id) = entity_extract_ids($type, $entity);
$identifier = $type . ':' . $id . ':' . $field_name . ':' . $state;
$cache = &drupal_static(__FUNCTION__, array());
if (isset($cache[$identifier])) {
// Return the cached result.
return $cache[$identifier];
}
$query = new EntityFieldQuery();
$query
->entityCondition('entity_type', 'og_membership')
->propertyCondition('entity_type', $type, '=')
->propertyCondition('etid', $id, '=')
->propertyCondition('field_name', $field_name, '=');
$field = field_info_field($field_name);
$states = count($args) == 2 ? FALSE : array($args[2]);
if ($state) {
$query->propertyCondition('state', $state, '=');
}
$result = og_get_entity_groups($type, $entity, $states, $field_name);
$target_type = $field['settings']['target_type'];
$result = $query->execute();
$cache[$identifier] = !empty($result['og_membership']) ? array_keys($result['og_membership']) : array();
return $cache[$identifier];
return !empty($result[$target_type]) ? array_keys($result[$target_type]) : array();
}
/**
......@@ -2261,13 +2244,15 @@ function og_user_access_entity($perm, $entity_type, $entity, $account = NULL) {
* "user", the current user will be used.
* @param $states
* (optional) Array with the state to return. Defaults to active.
* @param $field_name
* (optional) The field name associated with the group.
*
* @return
* An array with the group's entity type as the key, and array - keyed by
* the OG membership ID and the group ID as the value. If nothing found,
* then an empty array.
*/
function og_get_entity_groups($entity_type = 'user', $entity = NULL, $states = array(OG_STATE_ACTIVE)) {
function og_get_entity_groups($entity_type = 'user', $entity = NULL, $states = array(OG_STATE_ACTIVE), $field_name = NULL) {
$cache = &drupal_static(__FUNCTION__, array());
if ($entity_type == 'user' && empty($entity)) {
......@@ -2288,36 +2273,47 @@ function og_get_entity_groups($entity_type = 'user', $entity = NULL, $states = a
$state_identifier = implode(':', $states);
}
else {
$state_identifier = 0;
$state_identifier = FALSE;
}
if (isset($cache[$entity_type][$id][$state_identifier])) {
$identifier = array(
$entity_type,
$id,
$state_identifier,
$field_name,
);
$identifier = implode(':', $identifier);
if (isset($cache[$identifier])) {
// Return cached values.
return $cache[$entity_type][$id][$state_identifier];
return $cache[$identifier];
}
$cache[$entity_type][$id][$state_identifier] = array();
$cache[$identifier] = array();
$query = new EntityFieldQuery();
$query
->entityCondition('entity_type', 'og_membership')
->propertyCondition('entity_type', $entity_type, '=')
->propertyCondition('etid', $id, '=');
$query = db_select('og_membership', 'ogm')
->fields('ogm', array('id', 'gid', 'group_type'))
->condition('entity_type', $entity_type)
->condition('etid', $id);
if ($states) {
$query->propertyCondition('state', $states, 'IN');
$query->condition('state', $states, 'IN');
}
$result = $query->execute();
if (!empty($result['og_membership'])) {
// Get the group ID from the group membership.
$og_memberships = og_membership_load_multiple(array_keys($result['og_membership']));
foreach ($og_memberships as $og_membership) {
$cache[$entity_type][$id][$state_identifier][$og_membership->group_type][$og_membership->id] = $og_membership->gid;
}
if ($field_name) {
$query->condition('field_name', $field_name);
}
return $cache[$entity_type][$id][$state_identifier];
$result = $query
->execute()
->fetchAll();
foreach ($result as $row) {
$cache[$identifier][$row->group_type][$row->id] = $row->gid;
}
return $cache[$identifier];
}
......
......@@ -406,7 +406,7 @@ class OgMetaData extends DrupalWebTestCase {
$values += array('state' => $other_state);
og_group('entity_test', $entity2->pid, $values);
// Subscribe node to third group, using a diffferent field.
// Subscribe node to third group, using a different field.
$values += array('field_name' => 'og_ref_2');
og_group('entity_test', $entity3->pid, $values);
......@@ -1787,9 +1787,10 @@ class OgDeleteOrphansTestCase extends DrupalWebTestCase {
og_membership_orphans_worker($item->data);
// Load the node into a wrapper and verify we moved him to another group.
$wrapper = entity_metadata_wrapper('node', $first_node->nid);
$gids = og_get_entity_groups('node', $first_node->nid);
$gid = reset($gids['node']);
$this->assertTrue($wrapper->{OG_AUDIENCE_FIELD}->get(0)->getIdentifier() == $second_group->nid, "The node of the group moved to another group.");
$this->assertEqual($gid, $second_group->nid, 'The group content moved to another group.');
}
}
......
......@@ -17,17 +17,25 @@ class OgBehaviorHandler extends EntityReference_BehaviorHandler_Abstract {
*/
public function load($entity_type, $entities, $field, $instances, $langcode, &$items) {
// Get the OG memberships from the field.
$field_name = $field['field_name'];
$target_type = $field['settings']['target_type'];
foreach ($entities as $entity) {
$wrapper = entity_metadata_wrapper($entity_type, $entity);
if (empty($wrapper->{$field['field_name'] . '__og_membership'})) {
if (empty($wrapper->{$field_name})) {
// If the entity belongs to a bundle that was deleted, return early.
continue;
}
$id = $wrapper->getIdentifier();
$items[$id] = array();
foreach ($wrapper->{$field['field_name'] . '__og_membership'}->value() as $og_membership) {
$gids = og_get_entity_groups($entity_type, $entity, array(OG_STATE_ACTIVE), $field_name);
if (empty($gids[$target_type])) {
continue;
}
foreach ($gids[$target_type] as $gid) {
$items[$id][] = array(
'target_id' => $og_membership->gid,
'target_id' => $gid,
);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment