diff --git a/includes/og.field.inc b/includes/og.field.inc index 1b11fb1..eca7b53 100644 --- a/includes/og.field.inc +++ b/includes/og.field.inc @@ -70,12 +70,19 @@ function og_field_widget_form(&$form, &$form_state, $field, $instance, $langcode $entity_gids[] = $item['target_id']; } - $target_type = $field['settings']['target_type']; - $user_gids = og_get_entity_groups(); - $user_gids = !empty($user_gids[$target_type]) ? $user_gids[$target_type] : array(); + $mocked_instance = og_get_mocked_instance($instance, 'default'); + // Get the group ids available for selection in the audience field. + $field_gids = array(); + $ids = entityreference_get_selection_handler($field, $mocked_instance)->getReferencableEntities(); + if (!empty($ids)) { + foreach ($ids as $key => $values) { + $field_gids += $values; + } + $field_gids = array_keys($field_gids); + } - // Get the "Other group" group IDs. - $other_groups_ids = array_diff($entity_gids, $user_gids); + // Entity groups not shown in the audience field. + $other_groups_ids = array_diff($entity_gids, $field_gids); foreach ($field_modes as $field_mode) { $mocked_instance = og_get_mocked_instance($instance, $field_mode); @@ -107,7 +114,7 @@ function og_field_widget_form(&$form, &$form_state, $field, $instance, $langcode } else { // Keep only the groups that belong to the user and to the entity. - $my_group_ids = array_values(array_intersect($user_gids, $entity_gids)); + $my_group_ids = array_values(array_intersect($field_gids, $entity_gids)); $valid_ids = $my_group_ids ? entityreference_get_selection_handler($field, $mocked_instance, $entity_type, $dummy_entity)->validateReferencableEntities($my_group_ids) : array(); $valid_ids = $field['cardinality'] == 1 ? reset($valid_ids) : $valid_ids; diff --git a/og.test b/og.test index 9f78b23..47d0d82 100644 --- a/og.test +++ b/og.test @@ -915,7 +915,7 @@ class OgComplexWidgetTestCase extends DrupalWebTestCase { } function setUp() { - parent::setUp('og'); + parent::setUp('og', 'og_test'); // Add OG group field to a the node's "group" bundle. $this->drupalCreateContentType(array('type' => 'group')); @@ -1067,6 +1067,60 @@ class OgComplexWidgetTestCase extends DrupalWebTestCase { $this->assertOptionSelected('edit-og-group-ref-und-0-default', $group1->nid); $this->assertOptionSelected('edit-another-field-und-0-default', $group2->nid); } + + /** + * Test selection of groups added to audience field by external modules. + */ + function testAlteredAudienceField() { + // Add OG audience field we will alter in og_test_entity_query_alter(). + $this->drupalCreateContentType(array('type' => 'common')); + $og_field = og_fields_info(OG_AUDIENCE_FIELD); + og_create_field(OG_AUDIENCE_FIELD . '_altered', 'node', 'common', $og_field); + + $user1 = $this->drupalCreateUser(array('administer group', 'access content', 'create common content', 'edit any common content')); + $user2 = $this->drupalCreateUser(array('access content', 'create common content', 'edit any common content')); + + // Create group nodes. + $settings = array( + 'type' => 'group', + OG_GROUP_FIELD . '[und][0][value]' => 1, + ); + $settings['uid'] = $user1->uid; + $group1 = $this->drupalCreateNode($settings); + + $settings['uid'] = $user2->uid; + $group2 = $this->drupalCreateNode($settings); + + $settings = array( + 'type' => 'common', + ); + $settings['uid'] = $user1->uid; + $common1 = $this->drupalCreateNode($settings); + + $this->drupalLogin($user2); + + // Save node with membership in both groups. + $edit = array("og_group_ref_altered[und][0][default][]" => array( + $group1->nid => $group1->nid, + $group2->nid => $group2->nid, + )); + $this->drupalPost("node/$common1->nid/edit", $edit, 'Save'); + + // Assert user was able to post to both groups. + og_membership_invalidate_cache(); + $gids = og_get_entity_groups('node', $common1->nid); + $this->assertEqual(count($gids['node']), 2, 'Both groups selected.'); + + // Save node with no group memberships. + $edit = array("og_group_ref_altered[und][0][default][]" => array( + '_none' => '_none', + )); + $this->drupalPost("node/$common1->nid/edit", $edit, 'Save'); + + // Assert user was able to remove both groups. + og_membership_invalidate_cache(); + $this->assertFalse(og_get_entity_groups('node', $common1->nid), 'No groups selected.'); + } } /** diff --git a/tests/og_test.module b/tests/og_test.module index 0db5f3d..8e80054 100644 --- a/tests/og_test.module +++ b/tests/og_test.module @@ -89,3 +89,16 @@ function og_test_form_behavior_validate($element, &$form_state) { form_set_value($element, $value, $form_state); } + +/** + * Implements hook_entity_query_alter(). + * + * @see OgComplexWidgetTestCase::testAlteredAudienceField() + */ +function og_test_entity_query_alter($query) { + $instance = !empty($query->metaData['entityreference_selection_handler']->instance) ? $query->metaData['entityreference_selection_handler']->instance : array(); + if (!empty($query->metaData['field']['field_name']) && $query->metaData['field']['field_name'] == OG_AUDIENCE_FIELD . '_altered' && !empty($instance['field_mode']) && $instance['field_mode'] == 'default' && !empty($query->propertyConditions[0]['operator']) && $query->propertyConditions[0]['operator'] == 'IN') { + // Query all groups of entity_type node. + $query->propertyConditions[0]['value'] = og_get_all_group('node'); + } +}