Index: og_user_roles.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/og_user_roles/og_user_roles.install,v
retrieving revision 1.9
diff -u -p -r1.9 og_user_roles.install
--- og_user_roles.install	16 Jun 2009 21:44:47 -0000	1.9
+++ og_user_roles.install	16 Jul 2009 14:19:16 -0000
@@ -13,6 +13,13 @@ function og_user_roles_schema() {
     ),
     'primary key' => array('gid', 'uid', 'rid'),
   );
+  $schema['og_users_roles_group'] = array(
+    'fields' => array(
+      'gid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'default_role' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+    ),
+    'primary key' => array('gid'),
+  );
   return $schema;
 }
 
@@ -104,3 +111,21 @@ function og_user_roles_update_6203() {
   return $ret;
 }
 
+/**
+ * Create {og_users_roles_group} table.
+ */
+function og_user_roles_update_6204() {
+  $ret = array();
+  if (db_table_exists('og_users_roles_group')) {
+    return $ret;
+  }
+  db_create_table($ret, 'og_users_roles_group', array(
+    'fields' => array(
+      'gid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'default_role' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+    ),
+    'primary key' => array('gid'),
+  ));
+  return $ret;
+}
+
Index: og_user_roles.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/og_user_roles/og_user_roles.module,v
retrieving revision 1.38
diff -u -p -r1.38 og_user_roles.module
--- og_user_roles.module	1 Jul 2009 11:56:31 -0000	1.38
+++ og_user_roles.module	16 Jul 2009 14:19:16 -0000
@@ -30,6 +30,7 @@ function og_user_roles_help($path, $arg)
 function og_user_roles_perm() {
   return array(
     'configure member roles',
+    'override group default role',
   );
 }
 
@@ -319,7 +320,7 @@ function og_user_roles_og($op, $nid, $ui
   switch ($op) {
     case 'user insert':
       // Add default role for new group members, if configured.
-      if ($default_role = variable_get('og_user_roles_default_role', 0)) {
+      if ($default_role = og_user_roles_get_group_default_role($nid)) {
         og_user_roles_role_add($nid, $uid, $default_role);
       }
 
@@ -333,7 +334,7 @@ function og_user_roles_og($op, $nid, $ui
 
     case 'user update':
       $default_admin_role = variable_get('og_user_roles_default_admin_role', 0);
-      $default_role = variable_get('og_user_roles_default_role', 0);
+      $default_role = og_user_roles_get_group_default_role($nid);
       if ($default_admin_role > 0 && $default_admin_role != $default_role) {
         // Grant role for new group admin.
         if (isset($args['is_admin']) && $args['is_admin']) {
@@ -358,10 +359,32 @@ function og_user_roles_og($op, $nid, $ui
  */
 function og_user_roles_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
   switch ($op) {
+    case 'load':
+      if (og_is_group_type($node->type)) {
+        $node->og_user_roles_default_role = db_result(db_query("SELECT default_role FROM {og_users_roles_group} WHERE gid = %d", $node->nid));
+      }
+      break;
+
+    case 'insert':
+      if (og_is_group_type($node->type)) {
+        db_query("INSERT INTO {og_users_roles_group} (gid, default_role) VALUES (%d, %d)", $node->nid, $node->og_user_roles_default_role);
+      }
+      break;
+
+    case 'update':
+      if (og_is_group_type($node->type)) {
+        db_query("UPDATE {og_users_roles_group} SET default_role = %d WHERE gid = %d", $node->og_user_roles_default_role, $node->nid);
+        if (!db_affected_rows()) {
+          db_query("INSERT INTO {og_users_roles_group} (gid, default_role) VALUES (%d, %d)", $node->nid, $node->og_user_roles_default_role);
+        }
+      }
+      break;
+
     case 'delete':
       // Remove all data for a deleted group.
       if (og_is_group_type($node->type)) {
         db_query("DELETE FROM {og_users_roles} WHERE gid = %d", $node->nid);
+        db_query("DELETE FROM {og_users_roles_group} WHERE gid = %d", $node->nid);
       }
       break;
   }
@@ -380,6 +403,7 @@ function og_user_roles_form_user_admin_r
 function og_user_roles_user_admin_role_delete_submit($form, &$form_state) {
   // Remove all role assignments for deleted user role.
   db_query('DELETE FROM {og_users_roles} WHERE rid = %d', $form_state['values']['rid']);
+  db_query("DELETE FROM {og_users_roles_group} WHERE default_role = %d", $form_state['values']['rid']);
 }
 
 /**
@@ -444,3 +468,61 @@ function og_user_roles_role_delete($gid,
   }
 }
 
+/**
+ * Retrieve all roles assignable in a group.
+ */
+function og_user_roles_get_group_roles($node_type) {
+  $allowed_roles = array_filter(variable_get("og_user_roles_roles_{$node_type}", array()));
+  $user_roles = user_roles();
+  foreach ($allowed_roles as $rid => $checked) {
+    $roles[$rid] = $user_roles[$rid];
+  }
+  return $roles;
+}
+
+/**
+ * Implementation of hook_form_alter().
+ */
+function og_user_roles_form_alter(&$form, &$form_state, $form_id) {
+  // Add default user role option to node form.
+  if (isset($form['#node']) && $form_id == $form['#node']->type . '_node_form') {
+    $node = $form['#node'];
+    if (og_is_group_type($node->type) && user_access('override group default role')) {
+      $default = !empty($node->og_user_roles_default_role) ? $node->og_user_roles_default_role : variable_get('og_user_roles_default_role', 0);
+      $options = og_user_roles_get_group_roles($node->type);
+
+      $form['og_user_roles_default_role'] = array(
+        '#type' => 'select',
+        '#title' => t('Default role for new members'),
+        '#options' => $options,
+        '#default_value' => $default,
+        '#description' => t('Configure a default role to be assigned to new group members.'),
+      );
+    }
+  }
+}
+
+/**
+ * Implementation of hook_content_extra_fields().
+ */
+function og_user_roles_content_extra_fields($type_name) {
+  if (og_is_group_type($type_name)) {
+    $extra['og_user_roles_default_role'] = array(
+      'label' => t('Default role for new members'),
+      'description' => t('Configure a default role to be assigned to new group members.'),
+      'weight' => 0,
+    );
+    return $extra;
+  }
+}
+
+/**
+ * Return default role for a group.
+ */
+function og_user_roles_get_group_default_role($nid) {
+  $default_role = db_result(db_query("SELECT default_role FROM {og_users_roles_group} WHERE gid = %d", $nid));
+  if (!$default_role) {
+    $default_role = variable_get('og_user_roles_default_role', 0);
+  }
+  return $default_role;
+}
Index: og_user_roles.pages.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/og_user_roles/og_user_roles.pages.inc,v
retrieving revision 1.3
diff -u -p -r1.3 og_user_roles.pages.inc
--- og_user_roles.pages.inc	8 Jun 2009 13:00:05 -0000	1.3
+++ og_user_roles.pages.inc	16 Jul 2009 14:19:16 -0000
@@ -64,6 +64,7 @@ function og_user_roles_admin_settings() 
     '#title' => t('Default role for new group members'),
     '#options' => array(0 => t('None')) + $roles,
     '#default_value' => variable_get('og_user_roles_default_role', 0),
+    '#description' => t('This setting can be overridden at the group level by group admins with the "override group default role".'),
   );
 
   return system_settings_form($form);
@@ -75,11 +76,7 @@ function og_user_roles_admin_settings() 
 function og_user_roles_page($node) {
   drupal_set_title(t('Member roles for !title', array('!title' => l($node->title, "node/$node->nid"))));
 
-  $allowed_roles = array_filter(variable_get("og_user_roles_roles_{$node->type}", array()));
-  $user_roles = user_roles();
-  foreach ($allowed_roles as $rid => $checked) {
-    $roles[$rid] = $user_roles[$rid];
-  }
+  $roles = og_user_roles_get_group_roles($node->type);
 
   // Retrieve list of all group users
   $sql = og_list_users_sql(0, 0, 'ou.is_admin DESC, ou.is_active ASC, u.name ASC');
Index: tests/og_user_roles.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/og_user_roles/tests/og_user_roles.test,v
retrieving revision 1.2
diff -u -p -r1.2 og_user_roles.test
--- tests/og_user_roles.test	26 May 2009 05:35:06 -0000	1.2
+++ tests/og_user_roles.test	16 Jul 2009 14:19:16 -0000
@@ -118,5 +118,59 @@ class OGUserRolesTestCase extends OgTest
     $t_args = array('@type' => $this->og_post_type->name, '%title' => $node1->title);
     $this->assertRaw(t('@type %title has been updated.', $t_args), 'User can update post in group.');
   }
+
+  /**
+   * Test default user role for new members per group.
+   */
+  function testGroupDefaultUserRole() {
+    // Create and log in a group administrative user with content permissions.
+    $group_user = $this->drupalCreateUser(array(
+      'access content',
+      'administer nodes',
+    ));
+    $this->drupalLogin($group_user);
+
+    // Create a new group and verify group admin user can not modify default
+    // role for new members setting.
+    $this->drupalGet('node/' . $this->gid1 . '/edit');
+    $this->assertNoText(t('Default role for new members:'), 'Group admin user can not override group default role.');
+
+    // Log in admin user.
+    $this->drupalLogin($this->admin_user);
+
+    // Edit group gid2 and configure the group default role for new members.
+    $edit = array();
+    $edit['og_user_roles_default_role'] = $this->role_ogur;
+    $this->drupalPost('node/' . $this->gid2 . '/edit', $edit, t('Save'));
+
+    // Create another web user.
+    $web_user = $this->drupalCreateUser(array('access comments', 'access content'));
+
+    // Subscribe web user to group gid1 which has group-wide default user role.
+    $result = module_invoke('og', 'subscribe_user', $this->gid1, $web_user);
+    $this->assertTrue(isset($result['type']) && $result['type'] == 'subscribed', 'Web user subscribed to organic group.');
+
+    // Subscribe web user to group gid2 which has group specific default user role.
+    $result = module_invoke('og', 'subscribe_user', $this->gid2, $web_user);
+    $this->assertTrue(isset($result['type']) && $result['type'] == 'subscribed', 'Web user subscribed to organic group.');
+
+    // Load group posts.
+    $node2 = node_load($this->nid2);
+
+    // Log in web user.
+    $this->drupalLogin($web_user);
+
+    // Verify that user cannot edit group post belonging to group gid1.
+    $this->drupalGet('node/' . $this->nid1);
+    $this->assertNoLink('Edit');
+
+    // Verify that user can edit group post belonging to group gid2.
+    $this->drupalGet('node/' . $this->nid2);
+    $this->assertLink('Edit');
+    $this->clickLink('Edit');
+    $this->drupalPost(NULL, array(), 'Save');
+    $t_args = array('@type' => $this->og_post_type->name, '%title' => $node2->title);
+    $this->assertRaw(t('@type %title has been updated.', $t_args), 'User can update post in group.');
+  }
 }
 
