Index: og.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/og/og.module,v
retrieving revision 1.298.2.112
diff -u -r1.298.2.112 og.module
--- og.module	2 Dec 2007 01:48:05 -0000	1.298.2.112
+++ og.module	6 Dec 2007 22:43:43 -0000
@@ -13,6 +13,12 @@
 define('OG_VISIBLE_CHOOSE_PUBLIC', 2);
 define('OG_VISIBLE_CHOOSE_PRIVATE', 3);
 
+// visibility states for private groups. site admin chooses in og_settings()
+define('OG_PRIVATE_GROUPS_NEVER', 0);
+define('OG_PRIVATE_GROUPS_ALWAYS', 1);
+define('OG_PRIVATE_GROUPS_CHOOSE_TRUE', 2);
+define('OG_PRIVATE_GROUPS_CHOOSE_FALSE', 3);
+
 // site admin chooses in og_settings() whether group creator can put his group on the registration form
 define('OG_REGISTRATION_NEVER', 0);
 define('OG_REGISTRATION_ALWAYS', 1);
@@ -1107,11 +1113,8 @@
   
   $edit = $_POST['edit'];
 
-  // all group home pages are publically accessible as far as og is concerned. their posts may or may not be.
-  // change this via hook_form_alter() if you want subscriber only group home pages. this may become part of og.module one day
-  $form['og_public'] = array('#type' => 'value', '#value' => TRUE);
-  
   $form['og_description'] = array('#type' => 'textfield', '#title' => t('Description'), '#default_value' => $node->og_description, '#size' => 70, '#maxlength' => 150, '#required' => true, '#description' => t('A brief description for the group details block and the group directory.'), '#weight' => -4);
+  drupal_add_js(drupal_get_path('module', 'og'). '/og.js');
 
   if ($node->nid) {
     $default = $node->og_selective;
@@ -1167,10 +1170,48 @@
       $default = TRUE;
       // fall through
     case OG_DIRECTORY_CHOOSE_FALSE:
-      $form['og_directory'] = array('#type' => 'checkbox', '#title' => t('list in groups directory'),  '#default_value' => $node->nid ? $node->og_directory : $default, '#description' => t('Should this group appear on the !page?', array('!page' => l(t('list of groups page'),'og'))));
+      $form['og_directory'] = array('#type' => 'checkbox', '#title' => t('list in groups directory'),  '#default_value' => $node->nid ? $node->og_directory : $default, '#description' => t('Should this group appear on the !page?  Disabled if the group is set to <i>private group</i>.', array('!page' => l(t('list of groups page'),'og'))));
       break;    
   }
   
+  // private groups
+  $visibility = variable_get('og_private_groups', OG_PRIVATE_GROUPS_CHOOSE_FALSE);
+  // override setting for admins - get right default
+  if (user_access('administer nodes')) {
+    $visibility = in_array($visibility, array(OG_PRIVATE_GROUPS_NEVER, 
+                                              OG_PRIVATE_GROUPS_CHOOSE_FALSE)) 
+                  ? OG_PRIVATE_GROUPS_CHOOSE_FALSE : OG_PRIVATE_GROUPS_CHOOSE_TRUE;
+  }
+
+  $default = FALSE;
+  switch ($visibility) {
+    case OG_PRIVATE_GROUPS_NEVER :
+      $form['og_private'] = array (
+        '#type' => 'value',
+        '#value' => 0 
+      );
+      break;
+    
+    case OG_PRIVATE_GROUPS_ALWAYS :
+      $form['og_private'] = array (
+        '#type' => 'value',
+        '#value' => 1
+      );
+      break;
+
+    case OG_PRIVATE_GROUPS_CHOOSE_TRUE :
+      $default = TRUE;
+      // fall through
+
+    case OG_PRIVATE_GROUPS_CHOOSE_FALSE :
+      $form['og_private'] = array (
+        '#type' => 'checkbox',
+        '#title' => t('private group'), 
+        '#default_value' => $node->nid ? $node->og_private : $default, 
+        '#description' => t('Should this group be visible only by its subscribers?  Disabled if the group is set to <i>List in Directory</i>'));
+        break;
+  }
+  
   // language
   if (module_exists('locale') && $languages = locale_supported_languages()) {
     if (count($languages['name']) > 1) {
@@ -1229,20 +1270,20 @@
 }
 
 function og_load_group(&$node) {
-  $sql = 'SELECT selective AS og_selective, description AS og_description, theme AS og_theme, register AS og_register, directory AS og_directory, notification AS og_notification, language AS og_language FROM {og} WHERE nid = %d';
+  $sql = 'SELECT selective AS og_selective, description AS og_description, theme AS og_theme, register AS og_register, directory AS og_directory, notification AS og_notification, language AS og_language, private AS og_private FROM {og} WHERE nid = %d';
   $result = db_query($sql, $node->nid);
   $node = (object) array_merge((array)$node, (array)db_fetch_array($result));
   $node->comment = COMMENT_NODE_DISABLED; // we don't use comments on og nodes. technically not needed since we set this on node submit
 }
 
 function og_insert_group($node) {
-  $sql = "INSERT INTO {og} (nid, theme, selective, description, register, directory, notification, language) VALUES (%d, '%s', %d, '%s', %d, %d, %d, '%s')";
-  db_query($sql, $node->nid, $node->og_theme, $node->og_selective, $node->og_description, $node->og_register, $node->og_directory, $node->og_notification, $node->og_language);
+  $sql = "INSERT INTO {og} (nid, theme, selective, description, register, directory, notification, language, private) VALUES (%d, '%s', %d, '%s', %d, %d, %d, '%s', %d)";
+  db_query($sql, $node->nid, $node->og_theme, $node->og_selective, $node->og_description, $node->og_register, $node->og_directory, $node->og_notification, $node->og_language, $node->og_private);
 }
 
 function og_update_group($node) {
-  $sql = "UPDATE {og} SET theme = '%s', selective = %d, register = %d, description = '%s', directory = %d, notification = %d, language = '%s' WHERE nid = %d";
-  db_query($sql, $node->og_theme, $node->og_selective, $node->og_register, $node->og_description, $node->og_directory, $node->og_notification, $node->og_language, $node->nid);
+  $sql = "UPDATE {og} SET theme = '%s', selective = %d, register = %d, description = '%s', directory = %d, notification = %d, language = '%s', private = %d WHERE nid = %d";
+  db_query($sql, $node->og_theme, $node->og_selective, $node->og_register, $node->og_description, $node->og_directory, $node->og_notification, $node->og_language, $node->og_private, $node->nid);
 }
 
 // returns TRUE if node type should generate email notifications when posted to a group.
@@ -1566,6 +1607,20 @@
       $vis = OG_VISIBLE_BOTH;
     }
 
+    // If the post is to a private group, and $vis is not OG_VISIBLE_GROUPONLY, 
+    // override to OG_VISIBLE_CHOOSE_PRIVATE so that posts in private groups will never default to public.
+    if (count($gids) && $vis > OG_VISIBLE_GROUPONLY) {  
+      foreach ($gids as $gid) {
+        $group_node = new stdClass();
+        $group_node->nid = $gid;
+        og_load_group($group_node);
+         if ($group_node->og_private) {
+           $vis = OG_VISIBLE_CHOOSE_PRIVATE;
+          break;
+        }
+      }
+    } 
+
     switch ($vis) {
       case OG_VISIBLE_BOTH:
         $form['og_nodeapi']['og_public'] = array('#type' => 'value', '#value' => 1);
@@ -2091,8 +2146,15 @@
   if (og_is_group_type($node->type)) {
     // this grant allows group admins to manage stuff
     $grants[] = array('realm' => 'og_subscriber', 'gid' => $node->nid, 'grant_view' => 1, 'grant_update' => 1, 'grant_delete' => 1);
-    // this one lets everyone see group homepage. see 'private groups' issue if you don't want this. we need help.
-    $grants[] = array('realm' => 'og_public', 'gid' => 0, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0);
+    // If the group is not marked private let everyone view the group homepage.
+    if (!$node->og_private) {
+        $grants[] = array (
+          'realm' => 'og_public',
+          'gid' => 0,
+          'grant_view' => 1,
+          'grant_update' => 0,
+          'grant_delete' => 0 );
+    }
   }
   elseif (is_array($node->og_groups)) {
     // applies to non group nodes
@@ -2436,6 +2498,8 @@
   $form['#submit']['og_settings_submit'] = array(); // custom submit handler
   $form['#submit']['system_settings_form_submit'] = array(); // form.inc never calls the $callback if a submit handler is defined
   drupal_set_title(t('Organic groups configuration'));
+  drupal_add_js(drupal_get_path('module', 'og'). '/og.js'); // load the form javascript to handle private groups / node visibility conflicts in the og settings form.
+ 
   if (variable_get('og_enabled', 0)) {
     $status = t('enabled');
     $btn_text = t('Disable');
@@ -2467,6 +2531,19 @@
             );
   $form['og_settings']['group_details']['og_visibility_registration'] = array('#type' => 'radios', '#title' => t('Registration form control'), '#default_value' => variable_get('og_visibility_registration', OG_REGISTRATION_CHOOSE_FALSE), '#description' =>t('OG admins always see the checkbox for adding a group to the %dir. Note that changing this setting has no effect on existing posts. Re-save those posts to acquire this new setting.', array('%dir' => t('registration form'))), '#options' => $options);
     
+  // private groups control
+  $options = array(t('New group home pages and default audience are always public.'),
+               t('New group home pages and default audience are always private.'),
+               t('Group administrator chooses whether her group homepage and audience are private or not. Defaults to %yes.', array('%yes' => t('private'))),
+               t('Group administrator chooses whether her group homepage and audience are private or not. Defaults to %no.', array('%no' => t('public'))),
+             );
+  $form['og_settings']['group_details']['og_private_groups'] = array('#type' => 'radios', '#title' => t('Private Groups'), '#default_value' => variable_get('og_private_groups', OG_PRIVATE_GROUPS_CHOOSE_FALSE), 
+                                                                             '#description' =>t('A private group\'s group home page cannot be seen by non-subscribers, and new posts created in the group will default to being private.  This setting controls what private groups options can be used when creating a new group or editing an existing group.  If you select one of the <i>group administrator chooses</i> options then it will be up to group admins whether their new groups are private or not, with the default you specify here.  '.
+                                                                                                'Note that the privacy of all <i>content</i> in the group is determined as each node is created or edited, according to the <i>Node authoring form / Visibility of Posts</i> setting on this page.  Note also that changing this setting only affects the default for new groups being created, not the privacy of any existing groups!  To change those you must edit the groups and their individual content nodes directly.  If the setting you want is disabled here, check the settings under <i>Node authoring form / Visibility of Posts</i> on this page.  You cannot choose to only have private groups if nodes visibility is set to be always public, and vice versa.'
+                                                                                              ),                              
+                                                                              '#options' => $options, 
+                                                                   );
+
   // email notifications default
   $options = array(OG_NOTIFICATION_SELECTIVE => t('New registrants are not subscribed to group email notifications by default. A user may choose to enable this from her profile page or her my subscriptions page.'),
               OG_NOTIFICATION_ALWAYS => t('New registrants are subscribed to group email notifications by default. A user may choose to disable this from her profile page.'),
@@ -2477,7 +2554,7 @@
   $form['og_settings']['node_form']['og_help'] = array('#type' => 'textarea', '#default_value' => variable_get('og_help', ''), '#cols' => 70, '#rows' =>5, '#title' => t('Explanation or submission guidelines'), '#description' => t('This text will be displayed at the top of the group submission form.  It is useful for helping or instructing your users.'));
   $form['og_settings']['node_form']['og_audience_checkboxes'] = array('#type' => 'checkbox', '#title' => t('Audience checkboxes'), '#default_value' => variable_get('og_audience_checkboxes', TRUE), '#description' => t('Show each subscribed group as a checkbox in the Audience section. This enables user to place her post into multiple groups. If unchecked, simplify the user interface by omitting the checkboxes and assuming user wants to post into the current group. Group administrators always see checkboxes.'));
   $options = array(t('Visible only within the targeted groups'), t('Visible within the targeted groups and on other pages'), t('Visibility chosen by author/editor using a checkbox on the posting form. '). t('Checkbox defaults to @pub.', array('@pub' => t('Public'))), t('Visibility chosen by author/editor using a checkbox on the posting form. '). t('Checkbox defaults to @pri.', array('@pri' => t('Private'))));
-  $form['og_settings']['node_form']['og_visibility'] = array('#type' => 'radios', '#title' => t('Visibility of posts'), '#default_value' => variable_get('og_visibility', 0), '#description' =>t('Determine how broadly available a given post should be when it is affiliated with a group. OG admins always see the checkbox for making a post @pub. Note that changing this setting has no effect on existing posts. Re-save those posts to acquire this new setting.', array('@pub' => t('Public'))), '#options' => $options);  
+  $form['og_settings']['node_form']['og_visibility'] = array('#type' => 'radios', '#title' => t('Visibility of posts'), '#default_value' => variable_get('og_visibility', 0), '#description' =>t('Determine how broadly available a given post should be when it is affiliated with a group. OG admins always see the checkbox for making a post @pub. Note that changing this setting has no effect on existing posts. Re-save those posts to acquire this new setting.  If the setting you want is disabled here, check the settings under <i>Group details / Private Groups</i> on this page.  You cannot set node visibility to always be public if private groups are set to always on and vice versa.', array('@pub' => t('Public'))), '#options' => $options);  
 
   $options = array(t('optional'), t('required'));
   $form['og_settings']['node_form']['og_audience_required'] = array('#type' => 'radios', '#title' => t('Audience required'), '#default_value' => variable_get('og_audience_required', 0), '#options' => $options, '#description' => t('Do you require that all (non administrator) posts be affiliated with a group? Note that changing this setting will affect existing posts when they are edited.'));
Index: og.js
===================================================================
RCS file: /cvs/drupal/contributions/modules/og/og.js,v
retrieving revision 1.1.2.6
diff -u -r1.1.2.6 og.js
--- og.js	4 Sep 2007 03:23:09 -0000	1.1.2.6
+++ og.js	6 Dec 2007 22:43:42 -0000
@@ -1,10 +1,10 @@
 // $Id: og.js,v 1.1.2.6 2007/09/04 03:23:09 weitzman Exp $
 
 Drupal.ogAttach = function() {
-/*  Disable the public checkbox if no groups are selected in in Audience*/
+  /* Node authoring form for group content -Disable the public checkbox if no groups are selected in in Audience */
   $('.og-audience').click(function() {
     // Audience can be select or checkboxes
-		var cnt;
+    var cnt;
     if ( $('.og-audience .form-checkbox').size() > 0) {
       cnt = $('input.og-audience:checked').size();  
     }
@@ -18,19 +18,96 @@
       $('#edit-og-public').attr("disabled", "disabled");
     }
   });
+  if ( $('.og-audience .form-checkbox').size() > 0 ) {
+    if ( $('input.og-audience:checked').size() < 1) {
+        $('#edit-og-public').attr("disabled", "disabled");
+    }    
+  }
+  else {
+    if ( $('.og-audience option:selected').size() < 1) {
+        $('#edit-og-public').attr("disabled", "disabled");
+    }        
+  }
 
-	if ( $('.og-audience .form-checkbox').size() > 0 ) {
-	  if ( $('input.og-audience:checked').size() < 1) {
-	      $('#edit-og-public').attr("disabled", "disabled");
-	  }		
-	}
-	else {
-	  if ( $('.og-audience option:selected').size() < 1) {
-	      $('#edit-og-public').attr("disabled", "disabled");
-	  }				
-	}
-};
+  /* Node authoring form for group homepages - Don't allow "private group" and "list in groups diretory" at the same time */
+  $("#edit-og-private").click(function() { 
+    if ($("#edit-og-private:checked").val()) {
+      $("#edit-og-directory").attr('disabled','disabled');
+    }
+    else {
+      $("#edit-og-directory").removeAttr('disabled');
+    }
+  });
+  $("#edit-og-directory").click(function() {
+    if ($("#edit-og-directory:checked").val()) {
+      $("#edit-og-private").attr('disabled','disabled');
+    }
+    else {
+      $("#edit-og-private").removeAttr('disabled');
+    }
+  });
+  if ($("#edit-og-directory:checked").val() && !$("#edit-og-private:checked").val()) {
+      $("#edit-og-private").attr('disabled','disabled');
+  }
+  if ($("#edit-og-private:checked").val() && !$("#edit-og-directory:checked").val()) {
+      $("#edit-og-directory").attr('disabled','disabled');
+  } 
 
+  /* admin og settings form, "Group details - Private Groups"
+   * Disable "always public" if Node authoring visibility set to "Visible only within the targeted groups"
+   * Disable "always private" if Node authoring visibility set to "Visible within the targeted groups and on other pages"
+   */
+  $("input[@Name='og_visibility']").click(function() {
+    if ($("input[@Name='og_visibility']:checked").val() == 0) {
+        $("input[@name='og_private_groups']:nth(0)").attr('disabled','disabled');
+        $("input[@name='og_private_groups']:nth(1)").removeAttr('disabled');
+      }
+      else if ($("input[@Name='og_visibility']:checked").val() == 1) {
+        $("input[@name='og_private_groups']:nth(0)").removeAttr('disabled');
+        $("input[@name='og_private_groups']:nth(1)").attr('disabled','disabled');
+      } 
+      else {
+        $("input[@name='og_private_groups']:nth(0)").removeAttr('disabled');
+        $("input[@name='og_private_groups']:nth(1)").removeAttr('disabled');
+      }
+    }
+  );
+  if ($("input[@Name='og_visibility']:checked").val() == 0) {
+      $("input[@name='og_private_groups']:nth(0)").attr('disabled','disabled');
+      $("input[@name='og_private_groups']:nth(1)").removeAttr('disabled');
+  }
+  else if ($("input[@Name='og_visibility']:checked").val() == 1) {
+      $("input[@name='og_private_groups']:nth(0)").removeAttr('disabled');
+      $("input[@name='og_private_groups']:nth(1)").attr('disabled','disabled');     
+  }    
+  /* admin og settings form, "Node Authoring Form - Visibilty of Posts"
+   * Disable "Visible within the targeted groups and on other pages" if private groups set to "always private"
+   * Disable "Visible only within the targeted groups" if private groups set to "always public"
+   */
+  $("input[@Name='og_private_groups']").click(function() {
+      if ( $("input[@Name='og_private_groups']:checked").val() == 1 ) {
+        $("input[@name='og_visibility']:nth(0)").removeAttr('disabled');
+        $("input[@name='og_visibility']:nth(1)").attr('disabled','disabled');
+      }
+      else if ( $("input[@Name='og_private_groups']:checked").val() == 0 ) {
+        $("input[@name='og_visibility']:nth(0)").attr('disabled','disabled');
+        $("input[@name='og_visibility']:nth(1)").removeAttr('disabled');  
+      }
+      else { 
+        $("input[@name='og_visibility']:nth(0)").removeAttr('disabled');  
+        $("input[@name='og_visibility']:nth(1)").removeAttr('disabled');  
+      }
+    }
+  );
+  if ( $("input[@Name='og_private_groups']:checked").val() == 1 ) {
+    $("input[@name='og_visibility']:nth(0)").removeAttr('disabled');
+    $("input[@name='og_visibility']:nth(1)").attr('disabled','disabled');
+  }
+  else if ( $("input[@Name='og_private_groups']:checked").val() == 0 ) {
+      $("input[@name='og_visibility']:nth(0)").attr('disabled','disabled');
+      $("input[@name='og_visibility']:nth(1)").removeAttr('disabled');  
+  }
+};
 if (Drupal.jsEnabled) {
   $(document).ready(Drupal.ogAttach);
-}
\ No newline at end of file
+}
Index: og.install
===================================================================
RCS file: /cvs/drupal/contributions/modules/og/og.install,v
retrieving revision 1.21.2.15
diff -u -r1.21.2.15 og.install
--- og.install	20 Sep 2007 23:13:23 -0000	1.21.2.15
+++ og.install	6 Dec 2007 22:43:42 -0000
@@ -14,6 +14,7 @@
         directory int(1) NOT NULL default 0,
         notification int(1) NOT NULL default 0,
         language varchar(12) NOT NULL default '',
+        private int(1) NOT NULL default 0,
         PRIMARY KEY  (nid)
       ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
   
@@ -53,6 +54,7 @@
         directory numeric(1) NOT NULL default 0,
         notification numeric(1) NOT NULL default 0,
         language varchar(12) NOT NULL default '',
+        private numeric(1) NOT NULL default 0,  
         PRIMARY KEY  (nid)
       );");
 
@@ -421,6 +423,18 @@
   return array('Populated og_uid_global table');
 }
 
+function og_update_20() {
+  switch ($GLOBALS['db_type']) {
+  case 'mysql':
+  case 'mysqli':
+    $ret[] = update_sql("ALTER TABLE {og} ADD private int(1) NOT NULL default 0");
+    break;
+  case 'pgsql':
+    $ret[] = update_sql("ALTER TABLE {og} ADD private numeric(1) NOT NULL default 0");
+    break;
+  }
+  return $ret;
+}
 // end updates //
 
 function og_enable() {
