first commit
[step2_drupal.git] / og / modules / og_access / og_access.module
blobe6808bc8f90abc76a15e7cb26c1d9974685d2976
1 <?php
2 // $Id: og_access.module,v 1.32 2009/03/16 17:51:13 weitzman Exp $
4 // visibility states for private groups. site admin chooses in og_access_settings()
5 define('OG_PRIVATE_GROUPS_NEVER', 0);
6 define('OG_PRIVATE_GROUPS_ALWAYS', 1);
7 define('OG_PRIVATE_GROUPS_CHOOSE_TRUE', 2);
8 define('OG_PRIVATE_GROUPS_CHOOSE_FALSE', 3);
10 // visibility states for nodes within groups. site admin chooses in og_settings()
11 define('OG_VISIBLE_GROUPONLY', 0);
12 define('OG_VISIBLE_BOTH', 1);
13 define('OG_VISIBLE_CHOOSE_PUBLIC', 2);
14 define('OG_VISIBLE_CHOOSE_PRIVATE', 3);
16 function og_access_menu() {
17   $items['admin/og/og_access'] = array(
18     'title' => 'Organic groups access configuration',
19     'description' => 'Choose whether new groups should be private or public.',
20     'page callback' => 'drupal_get_form',
21     'page arguments' => array('og_access_settings'),
22     'access arguments' => array('administer site configuration'),
23   );
24   return $items;
27 function og_access_settings() {
28   drupal_add_js(drupal_get_path('module', 'og_access'). '/og_access.js'); // load the form javascript to handle private groups / node visibility conflicts in the og access settings form.
29   
30   $options = array(
31     t('Visible only within the targeted groups.'), 
32     t('Visible within the targeted groups and on other pages.'), 
33     t('Visibility chosen by author/editor using a checkbox on the posting form. Checkbox defaults to <em>public</em>.'), 
34     t('Visibility chosen by author/editor using a checkbox on the posting form. Checkbox defaults to <em>private</em>.')
35   );
36   $form['og_visibility'] = array(
37     '#type' => 'radios', 
38     '#title' => t('Visibility of posts'), 
39     '#default_value' => variable_get('og_visibility', 0), 
40     '#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 public. 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 <em>Private Groups</em> setting below. You cannot set node visibility to always be public if private groups are set to always on and vice versa.'), 
41     '#options' => $options,
42   );
43   
44   // private groups control
45   $options = array(
46     t('New group home pages and default audience are always public.'),
47     t('New group home pages and default audience are always private.'),
48     t('Group administrator chooses whether her group homepage and audience are private or not. Defaults to <em>private</em>.'),
49     t('Group administrator chooses whether her group homepage and audience are private or not. Defaults to <em>public</em>.'),
50   );
51   $form['og_private_groups'] = array(
52     '#type' => 'radios', 
53     '#title' => t('Private groups'), 
54     '#options' => $options, 
55     '#default_value' => variable_get('og_private_groups', OG_PRIVATE_GROUPS_CHOOSE_FALSE),    
56     '#description' => '<p>'. t("A private group's group home page cannot be seen by non-members, 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 <em>group administrator chooses</em> options then it will be up to group admins whether their new groups are private or not, with the default you specify here.") .'</p><p>'. t('Note that the privacy of all <em>content</em> in the group is determined as each node is created or edited, according to the <em>Visibility of Posts</em> 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 <em>Visibility of Posts</em> above. You cannot choose to only have private groups if node visibility is set to be always public, and vice versa.') .'</p>',                              
57   );
58   return system_settings_form($form);
61 /**
62  * Implementation of hook_content_extra_fields.
63  */
64 function og_access_content_extra_fields($type_name) {
65   $extra = array();
66   if (og_is_group_type($type_name)) {
67     $extra['og_private'] = array(
68       'label' => t('Private group'),
69       'description' => t('Checkbox for visibility of group home page to non-members.'),
70       'weight' => 0,
71     );
72   }
73   return $extra;
76 function og_access_alter_group_form(&$form, $node) {
77   // private groups
78   $visibility = variable_get('og_private_groups', OG_PRIVATE_GROUPS_CHOOSE_FALSE);
79   // override setting for admins - get right default
80   if (user_access('administer nodes')) {
81     $not = array(OG_PRIVATE_GROUPS_NEVER, OG_PRIVATE_GROUPS_CHOOSE_FALSE);
82     $visibility = in_array($visibility, $not) ? OG_PRIVATE_GROUPS_CHOOSE_FALSE : OG_PRIVATE_GROUPS_CHOOSE_TRUE;
83   }
85   $default = FALSE;
86   switch ($visibility) {
87     case OG_PRIVATE_GROUPS_NEVER :
88       $form['og_private'] = array (
89         '#type' => 'value',
90         '#value' => 0 
91       );
92       break;
93     
94     case OG_PRIVATE_GROUPS_ALWAYS :
95       $form['og_private'] = array (
96         '#type' => 'value',
97         '#value' => 1
98       );
99       break;
101     case OG_PRIVATE_GROUPS_CHOOSE_TRUE :
102       $default = TRUE;
103       // fall through
105     case OG_PRIVATE_GROUPS_CHOOSE_FALSE :
106       $form['og_private'] = array (
107         '#type' => 'checkbox',
108         '#title' => t('Private group'), 
109         '#default_value' => isset($node->nid) ? $node->og_private : $default, 
110         '#weight' => module_exists('content') ? content_extra_field_weight($node->type, 'og_private') : 0,        
111         '#description' => t('Should this group be visible only to its members? Disabled if the group is set to <em>List in Directory</em> or <em>Membership requests: open</em>.')
112       );
113       break;
114   }
117 // Add public checkbox to node edit form.
118 function og_access_alter_nongroup_form(&$form, $form_state, $node) {
119   global $user;
120   
121   // If user has no subscriptions, don't bother with Public checkbox - it's meaningless.
122   if (og_is_group_post_type($node->type) && !empty($form['og_nodeapi']['visible'])) {
123     // get the visibility for normal users
124     $vis = variable_get('og_visibility', 0);
126     // override visibility for og admins
127     if (user_access('administer organic groups')) {
128       if ($vis < 2) {
129         $vis = $vis == OG_VISIBLE_GROUPONLY ? OG_VISIBLE_CHOOSE_PRIVATE : OG_VISIBLE_CHOOSE_PUBLIC;
130       }
131     }
132     elseif (!og_get_subscriptions($user->uid)) {
133       // don't show checkbox if no memberships. must be public.
134       $vis = OG_VISIBLE_BOTH;
135     }
137     // We are using this form element to communicate $groups from og to og_access.
138     $groups = $form['og_initial_groups']['#value'];
139     
140     // If the post is to a private group, visibility must default to one of the private options.
141     $selected_groups = isset($form_state['values']['og_groups']) ? array_filter($form_state['values']['og_groups']) : $groups;
142     if (!empty($selected_groups)) {
143       foreach ($selected_groups as $gid) {
144         $group_node = new stdClass();
145         $group_node->nid = $gid;
146         og_load_group($group_node);
147          if (!empty($group_node->og_private)) {
148            // Try not to show checkbox if admin likes to reduce decisions for node authors.
149            $vis = variable_get('og_visibility', 0) == OG_VISIBLE_BOTH ? OG_VISIBLE_GROUPONLY : OG_VISIBLE_CHOOSE_PRIVATE;
150           break;
151         }
152       }
153     } 
154     else {
155       // TODOL: No groups. Public must be checked if it is visible.
156     }
158     switch ($vis) {
159       case OG_VISIBLE_BOTH:
160         $form['og_nodeapi']['og_public'] = array('#type' => 'value', '#value' => 1);
161         break;
162       case OG_VISIBLE_GROUPONLY:
163         $form['og_nodeapi']['og_public'] = array('#type' => 'value', '#value' => 0);
164         break;
166       //user decides how public the post is.
167       case OG_VISIBLE_CHOOSE_PUBLIC:
168         $form['og_nodeapi']['visible']['og_public'] = array(
169           '#type' => 'checkbox', 
170           '#title' => t('Public'), 
171           '#default_value' => isset($node->og_public) ? $node->og_public : 1, 
172           '#description' => t('Show this post to everyone, or only to members of the groups checked above. Posts without any groups are always <em>public</em>.'), 
173           '#weight' => 2,
174         );
175         break;
176       case OG_VISIBLE_CHOOSE_PRIVATE:
177         $form['og_nodeapi']['visible']['og_public'] = array(
178           '#type' => 'checkbox', 
179           '#title' => t('Public'), 
180           '#default_value' => isset($node->og_public) ? $node->og_public : 0, 
181           '#description' => t('Show this post to everyone, or only to members of the groups checked above. Posts without any groups are always <em>public</em>.'), 
182           '#weight' => 2,
183         );
184         break;
185     }
186     
187     if (count($form['og_nodeapi']['visible']) > 1) {
188       $form['og_nodeapi']['#type'] = 'fieldset';
189       $form['og_nodeapi']['#title'] = t('Groups');
190       $form['og_nodeapi']['#collapsible'] = TRUE;
191       $form['og_nodeapi']['#collapsed'] = $selected_groups ? TRUE : FALSE;
192     }
194   }
199  * Implementation of hook_form_alter().
200  */
201 function og_access_form_alter(&$form, &$form_state, $form_id) {
202   if (isset($form['#node']) && $form_id == $form['#node']->type .'_node_form') {
203     drupal_add_js(drupal_get_path('module', 'og_access'). '/og_access.js');
204     $node = $form['#node'];
205     if (og_is_group_type($node->type)) {
206       og_access_alter_group_form($form, $node);
207     }
208     else {
209       og_access_alter_nongroup_form($form, $form_state, $node);
210     }
211   }
215  * Implementation of hook_node_grants().
216  */
217 function og_access_node_grants($account, $op) { 
218   if ($op == 'view') {
219     $grants['og_public'][] = 0; // everyone can see a public node
220   }
222   // Subscribers get an admin or non-admin grant for each subscription
223   if ($subscriptions = og_get_subscriptions($account->uid)) {
224     foreach ($subscriptions as $key => $val) {
225       // Admins don't need to receive the subscriber grant since they can perform all operations.
226       if ($val['is_admin']) {
227         $grants['og_admin'][] = $key;
228       }
229       else {
230         $grants['og_subscriber'][] = $key;
231       }
232     }
233   }
234   return isset($grants) ? $grants : array();
238  * Implementation of hook_node_access_records.
239  */
240 function og_access_node_access_records($node) {
241   if (og_is_group_type($node->type)) {
242     // This grant allows group admins to manage their group.
243     $grants[] = array(
244       'realm' => 'og_admin', 
245       'gid' => $node->nid, 
246       'grant_view' => 1, 
247       'grant_update' => 1, 
248       'grant_delete' => 0,
249       'priority' => 0,
250     );
251     
252     if (!$node->og_private) {
253       // If the group is not private, let everyone view the group homepage.
254       $grants[] = array (
255         'realm' => 'og_public',
256         'gid' => 0,
257         'grant_view' => 1,
258         'grant_update' => 0,
259         'grant_delete' => 0,
260         'priority' => 0,
261       );
262     }
263     else {
264       // If the group private, let subscribers view the group homepage.
265       $grants[] = array (
266         'realm' => 'og_subscriber',
267         'gid' => $node->nid,
268         'grant_view' => 1,
269         'grant_update' => 0,
270         'grant_delete' => 0,
271         'priority' => 0,
272       );
274     }
275   }
276   elseif (!empty($node->og_groups)) {
277     // Applies to non group nodes.
278     if ($node->og_public) {
279       $grants[] = array(
280         'realm' => 'og_public', 
281         'gid' => 0, 
282         'grant_view' => 1, 
283         'grant_update' => 0, 
284         'grant_delete' => 0,
285         'priority' => 0,
286       );
287     }
288     
289     foreach ($node->og_groups as $gid) {
290       // Group administrators get all operations.
291       $grants[] = array(
292         'realm' => 'og_admin', 
293         'gid' => $gid, 
294         'grant_view' => 1, 
295         'grant_update' => 1, 
296         'grant_delete' => 1,
297         'priority' => 0,
298       );
299       // Normal subscribers just get update operation if node type is a wiki type.
300       $is_wiki = og_is_wiki_type($node->type);
301       $grants[] = array(
302         'realm' => 'og_subscriber', 
303         'gid' => $gid, 
304         'grant_view' => 1, 
305         'grant_update' => $is_wiki, 
306         'grant_delete' => 0,
307         'priority' => 0,
308       );
309     }
310   }
311       
312   if (!empty($grants)) {
313     // Allow other modules to change the grants.
314     drupal_alter('og_access_grants', $grants, $node);
315     return $grants;
316   }
317   return NULL;
321  * Implementation of hook_node_access_explain.
322  */
323 function og_access_node_access_explain($row) {
324   if ($row->realm == 'og_public') {
325     return t('All users may view this node.');
326   }
327   elseif ($row->realm == 'og_subscriber') {
328     $node = node_load((int)$row->gid);
329     return t('Members of <a href="@group-node">@group-name</a> may view this node.', array('@group-node' => url('node/'. $row->gid), '@group-name' => $node->title));
330   }
331   elseif ($row->realm == 'og_admin') {
332     $node = node_load((int)$row->gid);
333     return t('Group admins of <a href="@group-node">@group-name</a> may view/edit/delete this node.', array('@group-node' => url('node/'. $row->gid), '@group-name' => $node->title));
334   }