|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* @file |
|
4
|
|
|
* Code for the Commons Groups feature. |
|
5
|
|
|
*/ |
|
6
|
|
|
|
|
7
|
|
|
include_once 'commons_groups.features.inc'; |
|
8
|
|
|
|
|
9
|
|
|
/** |
|
10
|
|
|
* Implements hook_og_permission_alter(). |
|
11
|
|
|
*/ |
|
12
|
|
|
function commons_groups_og_permission_alter(&$perms) { |
|
13
|
|
|
// Rename the 'subscribe' and 'subscribe without approval' permissions to |
|
14
|
|
|
// better reflect their purpose in Commons. |
|
15
|
|
|
$perms['subscribe']['title'] = t('Contribute to the group'); |
|
16
|
|
|
$perms['subscribe']['description'] = t('This value is set automatically based on the "Group Privacy Settings" field.'); |
|
17
|
|
|
$perms['subscribe without approval']['title'] = t('Contribute to the group without approval'); |
|
18
|
|
|
$perms['subscribe without approval']['description'] = t('This value is set automatically based on the "Group Privacy Settings" field.'); |
|
19
|
|
|
} |
|
20
|
|
|
|
|
21
|
|
|
/** |
|
22
|
|
|
* Implements hook_form_FORM_ID_alter(). |
|
23
|
|
|
* |
|
24
|
|
|
* Hides permissions that are set automatically based on the "Group Privacy |
|
25
|
|
|
* Settings" field. |
|
26
|
|
|
*/ |
|
27
|
|
|
function commons_groups_form_og_ui_admin_permissions_alter(&$form, &$form_state) { |
|
|
|
|
|
|
28
|
|
|
$hidden_permissions = array('subscribe', 'subscribe without approval'); |
|
29
|
|
|
foreach ($hidden_permissions as $permission) { |
|
30
|
|
|
if (isset($form['permission'][$permission])) { |
|
31
|
|
|
$form['permission'][$permission]['#markup'] .= ' ' . t('<strong>Disabled by the Commons Groups module.<strong>'); |
|
32
|
|
|
} |
|
33
|
|
|
foreach ($form['checkboxes'] as $index => $elements) { |
|
34
|
|
|
if (isset($elements['#options'][$permission])) { |
|
35
|
|
|
unset($form['checkboxes'][$index]['#options'][$permission]); |
|
36
|
|
|
} |
|
37
|
|
|
} |
|
38
|
|
|
} |
|
39
|
|
|
} |
|
40
|
|
|
|
|
41
|
|
|
/** |
|
42
|
|
|
* Implements hook_ctools_plugin_directory(). |
|
43
|
|
|
*/ |
|
44
|
|
|
function commons_groups_ctools_plugin_directory($module, $plugin) { |
|
45
|
|
|
if ($module == 'entityreference') { |
|
46
|
|
|
return "plugins/entityreference/$plugin"; |
|
47
|
|
|
} |
|
48
|
|
|
} |
|
49
|
|
|
|
|
50
|
|
|
/** |
|
51
|
|
|
* Implements hook_modules_enabled(). |
|
52
|
|
|
* |
|
53
|
|
|
* Make sure the og access fields exist when og_access is enabled. |
|
54
|
|
|
*/ |
|
55
|
|
|
function commons_groups_modules_enabled($modules) { |
|
56
|
|
|
if (in_array('og_access', $modules)) { |
|
57
|
|
|
features_revert(array('commons_groups' => array('field_base'))); |
|
58
|
|
|
features_revert(array('commons_groups' => array('field_instance'))); |
|
59
|
|
|
} |
|
60
|
|
|
} |
|
61
|
|
|
|
|
62
|
|
|
/** |
|
63
|
|
|
* Implements hook_help(). |
|
64
|
|
|
* Used for the 3.2 -> 3.3 migration to warn users who have out-of-date groups |
|
65
|
|
|
* to make sure they update the group privacy settings. |
|
66
|
|
|
* See https://drupal.org/node/2059857 for more information |
|
67
|
|
|
*/ |
|
68
|
|
|
function commons_groups_help($path, $arg) { |
|
69
|
|
|
if (variable_get('commons_groups_needs_update', FALSE)) { |
|
70
|
|
|
$message = '<p>' . t("Drupal Commons 3.3 added a new, required field to control group privacy. Please edit your group(s) select one of the privacy options. Once all groups are |
|
71
|
|
|
set, an administrator can dismiss the update notice.") . '</p>'; |
|
72
|
|
|
if ($path == 'admin/content/groups/update') { |
|
73
|
|
|
return $message; |
|
74
|
|
|
} |
|
75
|
|
|
elseif ($arg[0] == 'node' && $arg[2] == 'edit') { |
|
76
|
|
|
$node = menu_get_object(); |
|
77
|
|
|
if($node->type == 'group' && empty($node->field_og_subscribe_settings)) { |
|
78
|
|
|
return $message; |
|
79
|
|
|
} |
|
80
|
|
|
} |
|
81
|
|
|
if (user_access('edit any group content')) { |
|
82
|
|
|
$message = t("Group privacy settings !updated.", array('!updated' => l('need to be updated', 'admin/content/groups/update'))); |
|
83
|
|
|
drupal_set_message($message, 'warning', FALSE); |
|
84
|
|
|
} |
|
85
|
|
|
} |
|
86
|
|
|
} |
|
87
|
|
|
|
|
88
|
|
|
/** |
|
89
|
|
|
* Implements hook_entity_view(). |
|
90
|
|
|
*/ |
|
91
|
|
|
function commons_groups_entity_view($entity, $type, $view_mode, $langcode) { |
|
|
|
|
|
|
92
|
|
|
// Set a breadcrumb for nodes in groups. We currently assume that |
|
93
|
|
|
// nodes are groups. |
|
94
|
|
|
if ($view_mode == 'full' && !empty($entity->og_group_ref[LANGUAGE_NONE][0]['target_id']) && $type != 'user') { |
|
95
|
|
|
$breadcrumb = array(); |
|
96
|
|
|
$breadcrumb[] = l(t('Home'), NULL); |
|
97
|
|
|
$breadcrumb[] = l(t('Groups'), 'groups'); |
|
98
|
|
|
$group = node_load($entity->og_group_ref[LANGUAGE_NONE][0]['target_id']); |
|
99
|
|
|
if (node_access('view', $group)) { |
|
100
|
|
|
$breadcrumb[] = l($group->title, 'node/' . $group->nid); |
|
101
|
|
|
} |
|
102
|
|
|
drupal_set_breadcrumb($breadcrumb); |
|
103
|
|
|
} |
|
104
|
|
|
} |
|
105
|
|
|
|
|
106
|
|
|
/** |
|
107
|
|
|
* Implements hook_form_BASE_FORM_ID_alter(). |
|
108
|
|
|
*/ |
|
109
|
|
|
function commons_groups_form_node_form_alter(&$form, &$form_state, $form_id) { |
|
|
|
|
|
|
110
|
|
|
$node = $form['#node']; |
|
111
|
|
|
|
|
112
|
|
|
list(, , $bundle) = entity_extract_ids('node', $node); |
|
113
|
|
|
|
|
114
|
|
|
// Customizations to the node form for entities that are group content. |
|
115
|
|
|
$group_content_entity_types = commons_groups_get_group_content_entity_types(); |
|
116
|
|
|
|
|
117
|
|
|
if (isset($group_content_entity_types['node'][$bundle])) { |
|
118
|
|
|
$form['actions']['submit']['#submit'][] = 'commons_groups_node_in_group_submit'; |
|
119
|
|
|
} |
|
120
|
|
|
|
|
121
|
|
|
// Hide the "Group content visibility" field to simplify the node form. |
|
122
|
|
|
if (!empty($form['group_content_access']['#access'])) { |
|
123
|
|
|
$form['group_content_access']['#access'] = FALSE; |
|
124
|
|
|
} |
|
125
|
|
|
|
|
126
|
|
|
// Alter the privacy settings fields. |
|
127
|
|
|
$groups = og_get_all_group_bundle(); |
|
128
|
|
|
|
|
129
|
|
|
if (isset($groups['node']) && in_array($bundle, array_keys($groups['node']))) { |
|
130
|
|
|
// The group privacy settings are not required. |
|
131
|
|
|
$form['field_og_subscribe_settings'][LANGUAGE_NONE]['#required'] = FALSE; |
|
132
|
|
|
|
|
133
|
|
|
if (module_exists('og_access')) { |
|
134
|
|
|
// Display private content checkbox only when "Joining requires approval" |
|
135
|
|
|
// is selected. |
|
136
|
|
|
$form['field_og_access_default_value']['#states'] = array( |
|
137
|
|
|
'visible' => array( |
|
138
|
|
|
':input[name="field_og_subscribe_settings[' . LANGUAGE_NONE . ']"]' => array('value' => 'approval'), |
|
139
|
|
|
), |
|
140
|
|
|
); |
|
141
|
|
|
|
|
142
|
|
|
$form['#after_build'] = array('commons_groups_form_group_node_after_build'); |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
|
|
$form['#attached']['css'][] = drupal_get_path('module', 'commons_groups') . '/css/commons_groups.css'; |
|
146
|
|
|
|
|
147
|
|
|
// The group access is set on commons_groups_node_presave(). |
|
148
|
|
|
$form['group_access'][LANGUAGE_NONE]['#required'] = FALSE; |
|
149
|
|
|
$form['group_access']['#access'] = FALSE; |
|
150
|
|
|
} |
|
151
|
|
|
} |
|
152
|
|
|
|
|
153
|
|
|
/** |
|
154
|
|
|
* After build callback for the group node form. |
|
155
|
|
|
* |
|
156
|
|
|
* Display the private content checkbox inside the privacy settings field. |
|
157
|
|
|
*/ |
|
158
|
|
|
function commons_groups_form_group_node_after_build($form, $form_state) { |
|
|
|
|
|
|
159
|
|
|
$form['field_og_subscribe_settings'][LANGUAGE_NONE]['approval']['#suffix'] = render($form['field_og_access_default_value']); |
|
160
|
|
|
|
|
161
|
|
|
return $form; |
|
162
|
|
|
} |
|
163
|
|
|
|
|
164
|
|
|
/** |
|
165
|
|
|
* Update the group permission field. |
|
166
|
|
|
* |
|
167
|
|
|
* @param $role |
|
168
|
|
|
* The OG role object of which the permissions are being changed. |
|
169
|
|
|
* @param $permissions |
|
170
|
|
|
* The anonymous user permissions of the group. |
|
171
|
|
|
*/ |
|
172
|
|
|
function _commons_groups_update_group_permissions($role, $permissions) { |
|
173
|
|
|
$updated_roles = &drupal_static(__FUNCTION__); |
|
174
|
|
|
if (!empty($updated_roles[$role->rid])) { |
|
175
|
|
|
// Avoid updating a group subscription twice on the same request. |
|
176
|
|
|
return; |
|
177
|
|
|
} |
|
178
|
|
|
|
|
179
|
|
|
if (!empty($permissions['subscribe without approval'])) { |
|
180
|
|
|
$subscribe_type = 'anyone'; |
|
181
|
|
|
} |
|
182
|
|
|
elseif (!empty($permissions['subscribe'])) { |
|
183
|
|
|
$subscribe_type = 'approval'; |
|
184
|
|
|
} |
|
185
|
|
|
else { |
|
186
|
|
|
$subscribe_type = 'invitation'; |
|
187
|
|
|
} |
|
188
|
|
|
|
|
189
|
|
|
$wrapper = entity_metadata_wrapper($role->group_type, $role->gid); |
|
190
|
|
|
if ($wrapper->field_og_subscribe_settings->value() != $subscribe_type) { |
|
191
|
|
|
// Mark that the group's permissions were already handled on this request, |
|
192
|
|
|
// to avoid saving the group entity more than once. |
|
193
|
|
|
$updated_roles[$role->rid] = TRUE; |
|
194
|
|
|
|
|
195
|
|
|
$wrapper->field_og_subscribe_settings->set($subscribe_type); |
|
196
|
|
|
$wrapper->save(); |
|
197
|
|
|
} |
|
198
|
|
|
} |
|
199
|
|
|
|
|
200
|
|
|
/** |
|
201
|
|
|
* Implements hook_menu_alter(). |
|
202
|
|
|
*/ |
|
203
|
|
|
function commons_groups_menu_alter(&$items) { |
|
204
|
|
|
// Provide a more informative title. |
|
205
|
|
|
if (isset($items['node/%/group'])) { |
|
206
|
|
|
$items['node/%/group']['title'] = t('Administer group'); |
|
207
|
|
|
} |
|
208
|
|
|
} |
|
209
|
|
|
|
|
210
|
|
|
/** |
|
211
|
|
|
* Implements hook_menu |
|
212
|
|
|
* Used with commons_groups_help and the commons groups update view to turn off |
|
213
|
|
|
* the warning message to update groups |
|
214
|
|
|
*/ |
|
215
|
|
|
function commons_groups_menu() { |
|
216
|
|
|
$items['admin/content/groups/update/toggle'] = array( |
|
|
|
|
|
|
217
|
|
|
'title' => 'Toggle Groups Update', |
|
218
|
|
|
'page callback' => 'commons_groups_update_toggle', |
|
219
|
|
|
'access arguments' => array('edit any group content'), |
|
220
|
|
|
'type' => MENU_CALLBACK, |
|
221
|
|
|
); |
|
222
|
|
|
return $items; |
|
223
|
|
|
} |
|
224
|
|
|
|
|
225
|
|
|
/** |
|
226
|
|
|
* Ajax callback page to toggle the group update status to off |
|
227
|
|
|
* See https://drupal.org/node/2059857 for more information |
|
228
|
|
|
*/ |
|
229
|
|
|
function commons_groups_update_toggle() { |
|
230
|
|
|
variable_set('commons_groups_needs_update', FALSE); |
|
231
|
|
|
return TRUE; |
|
232
|
|
|
} |
|
233
|
|
|
|
|
234
|
|
|
/** |
|
235
|
|
|
* Implements hook_block_info(). |
|
236
|
|
|
*/ |
|
237
|
|
|
function commons_groups_block_info() { |
|
238
|
|
|
$blocks['commons_groups_create_group'] = array( |
|
|
|
|
|
|
239
|
|
|
'info' => t('"Create a group" call to action'), |
|
240
|
|
|
'cache' => DRUPAL_NO_CACHE, |
|
241
|
|
|
); |
|
242
|
|
|
|
|
243
|
|
|
return $blocks; |
|
244
|
|
|
} |
|
245
|
|
|
|
|
246
|
|
|
/** |
|
247
|
|
|
* Implements hook_block_view(). |
|
248
|
|
|
*/ |
|
249
|
|
|
function commons_groups_block_view($delta = '') { |
|
250
|
|
|
$block = array(); |
|
251
|
|
|
|
|
252
|
|
|
switch ($delta) { |
|
253
|
|
|
case 'commons_groups_create_group': |
|
254
|
|
|
if (node_access('create', 'group')) { |
|
255
|
|
|
$block['subject'] = NULL; |
|
256
|
|
|
$block['content'] = array( |
|
257
|
|
|
'#type' => 'link', |
|
258
|
|
|
'#title' => t('Create a group'), |
|
259
|
|
|
'#href' => 'node/add/group', |
|
260
|
|
|
); |
|
261
|
|
|
} |
|
262
|
|
|
break; |
|
263
|
|
|
} |
|
264
|
|
|
|
|
265
|
|
|
return $block; |
|
266
|
|
|
} |
|
267
|
|
|
|
|
268
|
|
|
/** |
|
269
|
|
|
* Implements hook_views_pre_view(). |
|
270
|
|
|
* By default, all views should have a group_type filter that looks at only nodes. |
|
271
|
|
|
* This function allows those views to also show group content on the front page |
|
272
|
|
|
* regardless of their entity type. |
|
273
|
|
|
* See https://drupal.org/node/2037417 for more info. |
|
274
|
|
|
*/ |
|
275
|
|
|
function commons_groups_views_pre_view(&$view, &$display_id, &$args) { |
|
|
|
|
|
|
276
|
|
|
// We check to see if a group id argument is set in the view, and if no arguments |
|
277
|
|
|
// are being passed to the view. If so, the group_type filter is irrelevant. |
|
278
|
|
|
if (isset($view->display_handler->options['arguments']['gid']) && empty($args)) { |
|
279
|
|
|
if (isset($view->display_handler->options['filters']['group_type'])) { |
|
280
|
|
|
$filters = $view->display_handler->get_option('filters'); |
|
281
|
|
|
unset($filters['group_type']); |
|
282
|
|
|
$view->display_handler->override_option('filters', $filters); |
|
283
|
|
|
} |
|
284
|
|
|
} |
|
285
|
|
|
} |
|
286
|
|
|
|
|
287
|
|
|
function commons_groups_group_contributors_count_topics($group) { |
|
288
|
|
|
// Format the count of contributors. |
|
289
|
|
|
$output = ''; |
|
290
|
|
|
$view = views_get_view('commons_contributors_group'); |
|
291
|
|
|
if (!empty($view)) { |
|
292
|
|
|
$view->set_display('panel_pane_1'); |
|
293
|
|
|
$view->set_arguments(array($group->nid)); |
|
294
|
|
|
$view->get_total_rows = TRUE; |
|
295
|
|
|
$view->execute(); |
|
296
|
|
|
// If there are no contributors with avatars, return an empty string |
|
297
|
|
|
// rather than displaying '0 contributors'. |
|
298
|
|
|
if (empty($view->total_rows)) { |
|
299
|
|
|
return ''; |
|
300
|
|
|
} |
|
301
|
|
|
$contributors_count = $view->total_rows; |
|
302
|
|
|
$output .= l(format_plural($contributors_count, '1 contributor', '@count contributors'), 'node/' . $group->nid . '/contributors'); |
|
303
|
|
|
} |
|
304
|
|
|
// Format the list of topics: |
|
305
|
|
|
if (!empty($group->field_topics[LANGUAGE_NONE])) { |
|
306
|
|
|
foreach ($group->field_topics[LANGUAGE_NONE] as $item) { |
|
307
|
|
|
$tids[] = $item['tid']; |
|
|
|
|
|
|
308
|
|
|
} |
|
309
|
|
|
$topics = taxonomy_term_load_multiple($tids); |
|
|
|
|
|
|
310
|
|
|
$topics_text = ' discussing the @topics '; |
|
311
|
|
|
$t_args = array('@topics' => format_plural(count($topics), 'topic', 'topics')); |
|
312
|
|
|
foreach ($topics as $topic) { |
|
313
|
|
|
$topics_text .= '!topic-' . $topic->tid; |
|
314
|
|
|
if ($topic == end($topics)) { |
|
315
|
|
|
$topics_text .= '.'; |
|
316
|
|
|
} |
|
317
|
|
|
else { |
|
318
|
|
|
$topics_text .= ', '; |
|
319
|
|
|
} |
|
320
|
|
|
$t_args['!topic-' . $topic->tid] = l(t($topic->name), 'taxonomy/term/' . $topic->tid); |
|
321
|
|
|
} |
|
322
|
|
|
$output .= t($topics_text, $t_args); |
|
323
|
|
|
} |
|
324
|
|
|
return $output; |
|
325
|
|
|
} |
|
326
|
|
|
|
|
327
|
|
|
/* set commons_Groups form alter to happen after views bulk operations */ |
|
328
|
|
|
function commons_groups_module_implements_alter(&$implementations, $hook) { |
|
329
|
|
|
if ($hook == 'form_alter') { |
|
330
|
|
|
$group = $implementations['commons_groups']; |
|
331
|
|
|
unset($implementations['commons_groups']); |
|
332
|
|
|
$implementations['commons_groups'] = $group; |
|
333
|
|
|
} |
|
334
|
|
|
} |
|
335
|
|
|
|
|
336
|
|
|
/** |
|
337
|
|
|
* Implements hook_form_alter(). |
|
338
|
|
|
*/ |
|
339
|
|
|
function commons_groups_form_alter(&$form, &$form_state, $form_id) { |
|
|
|
|
|
|
340
|
|
|
if ($form_id == 'views_exposed_form' && strstr($form['#id'], 'views-exposed-form-commons-groups-directory')) { |
|
341
|
|
|
$form['groups-keys']['#attributes'] = array( |
|
342
|
|
|
'placeholder' => t('Separate keywords with commas'), |
|
343
|
|
|
); |
|
344
|
|
|
} |
|
345
|
|
|
if ((strstr($form_id, 'views_form_commons_group_moderation_page'))) { |
|
346
|
|
|
$form['select']['action::views_bulk_operations_delete_item']['#weight'] = 9; |
|
347
|
|
|
} |
|
348
|
|
|
if ($form_id == 'group_node_form' && is_null($form['nid']['#value'])) { |
|
349
|
|
|
$form['actions']['submit']['#submit'][] = 'commons_groups_group_submission_message'; |
|
350
|
|
|
} |
|
351
|
|
|
if (in_array($form_id, array('og_ui_admin_global_permissions', 'og_ui_admin_permissions'))) { |
|
352
|
|
|
$group_content_entity_types = commons_groups_get_group_content_entity_types(); |
|
353
|
|
|
if (!empty($group_content_entity_types)) { |
|
354
|
|
|
// @TODO: Improve this message to be more specific and/or |
|
355
|
|
|
// reflect these changes in the checkboxes. |
|
356
|
|
|
$message = 'In addition to the permissions listed here, the Commons Groups module grants non-group members the ability to post content into groups where content in the group is public.'; |
|
357
|
|
|
drupal_set_message(t($message), 'warning'); |
|
358
|
|
|
} |
|
359
|
|
|
} |
|
360
|
|
|
// Hide internal fields that the user should not be able to edit directly. |
|
361
|
|
|
if ($form_id == 'edit_profile_user_profile_form' || substr($form_id, -10) === '_node_form') { |
|
362
|
|
|
$internal_fields = array('field_unread_invitations', 'field_unread_messages', 'user_trusted_contacts', 'og_user_group_ref', 'group_access'); |
|
363
|
|
|
foreach ($internal_fields as $field_name) { |
|
364
|
|
|
if(isset($form[$field_name])) { |
|
365
|
|
|
$form[$field_name]['#access'] = FALSE; |
|
366
|
|
|
} |
|
367
|
|
|
} |
|
368
|
|
|
} |
|
369
|
|
|
// Disable Trusted Contacts field if commons_trusted_contacts is disabled. |
|
370
|
|
|
$group_content_entity_types = commons_groups_get_group_content_entity_types(); |
|
371
|
|
|
if (isset($form['#node']->type) && isset($group_content_entity_types['node'][$form['#node']->type])) { |
|
372
|
|
|
if (isset($form['og_user_group_ref']) && !module_exists('commons_trusted_contacts')) { |
|
373
|
|
|
$form['og_user_group_ref']['#access'] = FALSE; |
|
374
|
|
|
} |
|
375
|
|
|
} |
|
376
|
|
|
} |
|
377
|
|
|
|
|
378
|
|
|
/** |
|
379
|
|
|
* Submit handler called if the form is for a node enabled as group content. |
|
380
|
|
|
*/ |
|
381
|
|
|
function commons_groups_node_in_group_submit(&$form, &$form_state) { |
|
|
|
|
|
|
382
|
|
|
if (isset($form_state['values']['og_group_ref'][LANGUAGE_NONE][0])) { |
|
383
|
|
|
$group = $form_state['values']['og_group_ref'][LANGUAGE_NONE][0]['target_id']; |
|
384
|
|
|
$form_state['redirect'] = 'node/' . $group; |
|
385
|
|
|
} |
|
386
|
|
|
} |
|
387
|
|
|
|
|
388
|
|
|
/** |
|
389
|
|
|
* Implements hook_system_info_alter(). |
|
390
|
|
|
*/ |
|
391
|
|
|
function commons_groups_system_info_alter(&$info, $file, $type) { |
|
|
|
|
|
|
392
|
|
|
// Commons Groups dynamically adds the og_group_ref field to |
|
393
|
|
|
// content types that request it by altering the |
|
394
|
|
|
// commons_groups_entity_types variable. |
|
395
|
|
|
// We must add a corresponding line for each field instance |
|
396
|
|
|
// to commons_groups.info so that Features is aware of the instance |
|
397
|
|
|
// and can successfully revert the field_instance component back |
|
398
|
|
|
// to its default state. |
|
399
|
|
|
if ($file->name == 'commons_groups') { |
|
400
|
|
|
$group_bundles = og_get_all_group_bundle(); |
|
401
|
|
|
if (!empty($group_bundles['node'])) { |
|
402
|
|
|
foreach ($group_bundles['node'] as $bundle => $name) { |
|
403
|
|
|
// These field instances should be added to groups regardless of |
|
404
|
|
|
// whether og_access.module is enabled. |
|
405
|
|
|
$info['features']['field_instance'][] = "node-$bundle-field_og_access_default_value"; |
|
406
|
|
|
$info['features']['field_instance'][] = "node-$bundle-field_og_subscribe_settings"; |
|
407
|
|
|
$info['features']['field_instance'][] = "node-$bundle-og_roles_permissions"; |
|
408
|
|
|
$info['features']['field_instance'][] = "node-$bundle-body"; |
|
409
|
|
|
$info['features']['field_instance'][] = "node-$bundle-group_group"; |
|
410
|
|
|
|
|
411
|
|
|
// These fields are only necessary when og_access.module is enabled. |
|
412
|
|
|
$info['features']['field_instance'][] = "node-$bundle-group_access"; |
|
413
|
|
|
$info['features']['field_instance'][] = "node-$bundle-field_group_logo"; |
|
414
|
|
|
|
|
415
|
|
|
// Add default strongarm settings. |
|
416
|
|
|
$info['features']['variable'][] = "comment_anonymous_$bundle"; |
|
417
|
|
|
$info['features']['variable'][] = "comment_default_mode_$bundle"; |
|
418
|
|
|
$info['features']['variable'][] = "comment_default_per_page_$bundle"; |
|
419
|
|
|
$info['features']['variable'][] = "comment_form_location_$bundle"; |
|
420
|
|
|
$info['features']['variable'][] = "comment_$bundle"; |
|
421
|
|
|
$info['features']['variable'][] = "comment_preview_$bundle"; |
|
422
|
|
|
$info['features']['variable'][] = "comment_subject_field_$bundle"; |
|
423
|
|
|
$info['features']['variable'][] = "field_bundle_settings_node__$bundle"; |
|
424
|
|
|
} |
|
425
|
|
|
} |
|
426
|
|
|
$group_content_entity_types = commons_groups_get_group_content_entity_types(); |
|
427
|
|
|
if (!empty($group_content_entity_types)) { |
|
428
|
|
|
foreach ($group_content_entity_types as $entity_type => $bundles) { |
|
429
|
|
|
foreach (array_keys($bundles) as $bundle) { |
|
430
|
|
|
$info['features']['field_instance'][] = "$entity_type-$bundle-og_group_ref"; |
|
431
|
|
|
$info['features']['field_instance'][] = "$entity_type-$bundle-group_content_access"; |
|
432
|
|
|
} |
|
433
|
|
|
} |
|
434
|
|
|
} |
|
435
|
|
|
|
|
436
|
|
|
// Commons specific group variables. |
|
437
|
|
|
$commons_groups = commons_groups_get_group_types(); |
|
438
|
|
|
if (isset($commons_groups['node'])) { |
|
439
|
|
|
foreach ($commons_groups['node'] as $bundle => $group_info) { |
|
440
|
|
|
$info['features']['variable'][] = "node_options_$bundle"; |
|
441
|
|
|
$info['features']['variable'][] = "node_preview_$bundle"; |
|
442
|
|
|
$info['features']['variable'][] = "node_submitted_$bundle"; |
|
443
|
|
|
$info['features']['variable'][] = "og_group_manager_default_rids_node_$bundle"; |
|
444
|
|
|
} |
|
445
|
|
|
} |
|
446
|
|
|
} |
|
447
|
|
|
|
|
448
|
|
|
// Dynamically adding a field instance to an entity type results in features |
|
449
|
|
|
// automatically detecting Commons Groups as a dependency. |
|
450
|
|
|
// We manually exclude the dependency in order to prevent entity type provider |
|
451
|
|
|
// modules from appearing overridden and to allow them to be used |
|
452
|
|
|
// independently of Commons Groups. |
|
453
|
|
|
$commons_entity_integrations = &drupal_static(__FUNCTION__); |
|
454
|
|
|
|
|
455
|
|
View Code Duplication |
if (!isset($commons_entity_integrations)) { |
|
|
|
|
|
|
456
|
|
|
foreach (module_implements('commons_entity_integration') as $module) { |
|
457
|
|
|
$commons_entity_integrations[$module] = call_user_func($module . '_commons_entity_integration'); |
|
458
|
|
|
} |
|
459
|
|
|
} |
|
460
|
|
|
|
|
461
|
|
View Code Duplication |
if (isset($commons_entity_integrations[$file->name])) { |
|
|
|
|
|
|
462
|
|
|
foreach ($commons_entity_integrations[$file->name] as $entity_type => $integration) { |
|
463
|
|
|
foreach ($integration as $bundle => $options) { |
|
464
|
|
|
if (commons_groups_is_group_content($entity_type, $bundle)) { |
|
465
|
|
|
$info['features_exclude']['dependencies']['commons_groups'] = 'commons_groups'; |
|
466
|
|
|
} |
|
467
|
|
|
} |
|
468
|
|
|
} |
|
469
|
|
|
} |
|
470
|
|
|
} |
|
471
|
|
|
|
|
472
|
|
|
/** |
|
473
|
|
|
* Implements hook_default_message_type_alter(). |
|
474
|
|
|
*/ |
|
475
|
|
|
function commons_groups_default_message_type_alter(&$defaults) { |
|
476
|
|
|
foreach (array('commons_activity_streams_comment_created', 'commons_activity_streams_node_created') as $name) { |
|
477
|
|
|
if (!empty($defaults[$name])) { |
|
478
|
|
|
$defaults[$name]->message_text[LANGUAGE_NONE][2] = commons_groups_message_partial_default(); |
|
479
|
|
|
} |
|
480
|
|
|
} |
|
481
|
|
|
} |
|
482
|
|
|
|
|
483
|
|
|
|
|
484
|
|
|
/** |
|
485
|
|
|
* Implements hook_og_user_access_alter(). |
|
486
|
|
|
* |
|
487
|
|
|
* Deny create permissions from non-members on "non-public" groups (i.e. groups |
|
488
|
|
|
* that don't allow joining without approval). |
|
489
|
|
|
*/ |
|
490
|
|
|
function commons_groups_og_user_access_alter(&$perm, $context) { |
|
491
|
|
|
$account = $context['account']; |
|
492
|
|
|
$group_type = $context['group_type']; |
|
493
|
|
|
$group = $context['group']; |
|
494
|
|
|
|
|
495
|
|
|
if ($group_type != 'node') { |
|
496
|
|
|
return; |
|
497
|
|
|
} |
|
498
|
|
|
// The purpose of this function is to grant permissions to create content |
|
499
|
|
|
// in a group to non-members of the group, when the group's privacy settings |
|
500
|
|
|
// (field_og_subscribe_settings) is set to "Anyone can contribute". |
|
501
|
|
|
if (og_is_member($group_type, $group->nid, 'user', $account, array(OG_STATE_ACTIVE, OG_STATE_PENDING, OG_STATE_BLOCKED))) { |
|
502
|
|
|
// The user is a group member, so comply to the OG permissions. |
|
503
|
|
|
return; |
|
504
|
|
|
} |
|
505
|
|
|
|
|
506
|
|
|
$wrapper = entity_metadata_wrapper($group_type, $group); |
|
507
|
|
|
$access_create = $account->uid && $wrapper->field_og_subscribe_settings->value() == 'anyone'; |
|
508
|
|
|
|
|
509
|
|
|
// Make sure user can view group (i.e. it's not private). |
|
510
|
|
|
$commons_groups_entity_types = commons_groups_get_group_content_entity_types(); |
|
511
|
|
|
foreach (array_keys($commons_groups_entity_types['node']) as $type) { |
|
512
|
|
|
$perm["create $type content"] = $access_create; |
|
513
|
|
|
} |
|
514
|
|
|
} |
|
515
|
|
|
|
|
516
|
|
|
|
|
517
|
|
|
/** |
|
518
|
|
|
* Implements of hook_token_info(). |
|
519
|
|
|
*/ |
|
520
|
|
|
function commons_groups_token_info() { |
|
521
|
|
|
$types = array(); |
|
522
|
|
|
$tokens = array(); |
|
523
|
|
|
|
|
524
|
|
|
// Commons Groups tokens. |
|
525
|
|
|
$types['commons-groups'] = array( |
|
526
|
|
|
'name' => t('Commons Groups'), |
|
527
|
|
|
'description' => t('Tokens related to the Groups functionality in Drupal Commons.'), |
|
528
|
|
|
'needs-data' => 'node', |
|
529
|
|
|
); |
|
530
|
|
|
$tokens['commons-groups']['in-groups-text'] = array( |
|
531
|
|
|
'name' => t('"In groups" text'), |
|
532
|
|
|
'description' => t('The text (starting with "in the groups") indicating which groups a piece of content belongs to.'), |
|
533
|
|
|
); |
|
534
|
|
|
$tokens['node']['commons-groups-first-group'] = array( |
|
535
|
|
|
'name' => t('First Group'), |
|
536
|
|
|
'description' => t('First group associated with a piece of content. Useful for path aliases'), |
|
537
|
|
|
); |
|
538
|
|
|
$tokens['node']['commons-groups-group-contributors-count-topics'] = array( |
|
539
|
|
|
'name' => t('Commons Groups: Group contributor count and topics'), |
|
540
|
|
|
'description' => t('Displays text showing the number of contributors and the topics associated with a group node.'), |
|
541
|
|
|
); |
|
542
|
|
|
return array( |
|
543
|
|
|
'types' => $types, |
|
544
|
|
|
'tokens' => $tokens, |
|
545
|
|
|
); |
|
546
|
|
|
} |
|
547
|
|
|
|
|
548
|
|
|
/** |
|
549
|
|
|
* Implements hook_tokens(). |
|
550
|
|
|
*/ |
|
551
|
|
|
function commons_groups_tokens($type, $tokens, $data = array(), $options = array()) { |
|
|
|
|
|
|
552
|
|
|
$replacements = array(); |
|
553
|
|
|
if ($type == 'node' && !empty($data['node'])) { |
|
554
|
|
|
$group = $data['node']; |
|
555
|
|
|
|
|
556
|
|
|
foreach ($tokens as $name => $original) { |
|
557
|
|
|
if ($name == 'commons-groups-group-contributors-count-topics') { |
|
558
|
|
|
$replacements[$original] = commons_groups_group_contributors_count_topics($group); |
|
559
|
|
|
return $replacements; |
|
560
|
|
|
} |
|
561
|
|
|
} |
|
562
|
|
|
} |
|
563
|
|
|
if ($type == 'commons-groups') { |
|
564
|
|
|
if (!empty($tokens['in-groups-text'])) { |
|
565
|
|
|
// Build a list of groups associated with this message. |
|
566
|
|
|
$text = ''; |
|
567
|
|
|
$target_nids = array(); |
|
568
|
|
|
$related_groups = array(); |
|
|
|
|
|
|
569
|
|
|
$related_gids = array(); |
|
570
|
|
|
|
|
571
|
|
|
// First, build an array of target nodes associated with the message. |
|
572
|
|
|
foreach ($data['message']->field_target_nodes[LANGUAGE_NONE] as $key => $value) { |
|
573
|
|
|
$target_nids[] = $value['target_id']; |
|
574
|
|
|
} |
|
575
|
|
|
// If there are no target nodes, the in-groups-text token should be empty. |
|
576
|
|
|
if (empty($target_nids)) { |
|
577
|
|
|
$replacements['[commons-groups:in-groups-text]'] = $text; |
|
578
|
|
|
return $replacements; |
|
579
|
|
|
} |
|
580
|
|
|
// Build a list of groups associated with the target nodes. |
|
581
|
|
|
// For now, we assume that the group type is node. |
|
582
|
|
|
foreach ($target_nids as $key => $nid) { |
|
583
|
|
|
$og_memberships_this_target = og_get_entity_groups('node', $nid); |
|
584
|
|
|
if (!empty($og_memberships_this_target['node'])) { |
|
585
|
|
|
$og_memberships_this_target = $og_memberships_this_target['node']; |
|
586
|
|
|
foreach ($og_memberships_this_target as $membership_id => $gid) { |
|
587
|
|
|
$related_gids[] = $gid; |
|
588
|
|
|
} |
|
589
|
|
|
} |
|
590
|
|
|
} |
|
591
|
|
|
// If no groups are associated with any of the target nodes, |
|
592
|
|
|
// then we have no "in the groups" text. |
|
593
|
|
|
if (empty($related_gids)) { |
|
594
|
|
|
$replacements['[commons-groups:in-groups-text]'] = ''; |
|
595
|
|
|
return $replacements; |
|
596
|
|
|
} |
|
597
|
|
|
|
|
598
|
|
|
$related_groups = entity_load('node', $related_gids); |
|
599
|
|
|
// Key the array of groups in a predictable way. |
|
600
|
|
|
$related_groups = array_values($related_groups); |
|
601
|
|
|
// Generate the appropriate text depending on the number of groups |
|
602
|
|
|
// associated with the message: |
|
603
|
|
|
$replacements['[commons-groups:in-groups-text]'] = commons_groups_related_groups_text($related_groups); |
|
604
|
|
|
return $replacements; |
|
605
|
|
|
} |
|
606
|
|
|
} |
|
607
|
|
|
if ($type == 'node' && !empty($data['node'])) { |
|
608
|
|
|
if (!empty($tokens['commons-groups-first-group'])) { |
|
609
|
|
|
$group = $data['node']; |
|
610
|
|
|
$text = ''; |
|
611
|
|
|
|
|
612
|
|
|
if (!empty($group->og_group_ref[LANGUAGE_NONE])) { |
|
613
|
|
|
$wrapper = entity_metadata_wrapper('node', $group); |
|
614
|
|
|
$groups = $wrapper->og_group_ref->value(); |
|
615
|
|
|
|
|
616
|
|
|
// Return the title of the first group associated with this node. |
|
617
|
|
|
$first_group = array_shift($groups); |
|
618
|
|
|
|
|
619
|
|
|
// Use the title field by default and fall back to the node title. |
|
620
|
|
|
$first_group_wrapper = entity_metadata_wrapper('node', $first_group); |
|
621
|
|
|
$text = isset($first_group_wrapper->title_field) ? $first_group_wrapper->title_field->value() : $first_group_wrapper->label(); |
|
622
|
|
|
} |
|
623
|
|
|
$replacements['[node:commons-groups-first-group]'] = $text; |
|
624
|
|
|
return $replacements; |
|
625
|
|
|
} |
|
626
|
|
|
} |
|
627
|
|
|
} |
|
628
|
|
|
|
|
629
|
|
|
function commons_groups_message_partial_default() { |
|
630
|
|
|
$partial = array( |
|
631
|
|
|
'value' => '[commons-groups:in-groups-text]', |
|
632
|
|
|
'format' => 'full_html', |
|
633
|
|
|
'safe_value' => '[commons-groups:in-groups-text]', |
|
634
|
|
|
); |
|
635
|
|
|
return $partial; |
|
636
|
|
|
} |
|
637
|
|
|
|
|
638
|
|
|
/** |
|
639
|
|
|
* Build the related-groups text for nodes. |
|
640
|
|
|
* |
|
641
|
|
|
* @param $related_groups |
|
642
|
|
|
* Array of groups referenced by the node. |
|
643
|
|
|
* |
|
644
|
|
|
* @return |
|
645
|
|
|
* String containing the related groups. |
|
646
|
|
|
*/ |
|
647
|
|
|
function commons_groups_related_groups_text($related_groups) { |
|
648
|
|
|
// In 1 group: "in the x group" |
|
649
|
|
|
if (count($related_groups) == 1) { |
|
650
|
|
|
return t(' in the !group group', array('!group' => l($related_groups[0]->title, 'node/' . $related_groups[0]->nid))); |
|
651
|
|
|
} |
|
652
|
|
|
|
|
653
|
|
|
// In 2 groups: "in the x and y groups" |
|
654
|
|
|
if (count($related_groups) == 2) { |
|
655
|
|
|
return t(' in the !group-0 and !group-1 groups', array( |
|
656
|
|
|
'!group-0' => l($related_groups[0]->title, 'node/' . $related_groups[0]->nid), |
|
657
|
|
|
'!group-1' => l($related_groups[1]->title, 'node/' . $related_groups[1]->nid), |
|
658
|
|
|
)); |
|
659
|
|
|
} |
|
660
|
|
|
|
|
661
|
|
|
// In more than 2 groups: "in the x, y and z groups" |
|
662
|
|
|
if (count($related_groups) > 2) { |
|
663
|
|
|
// Separate the last group. |
|
664
|
|
|
$last_group = array_pop($related_groups); |
|
665
|
|
|
$text = ' in the '; |
|
666
|
|
|
// Prepare tokens for t() for each of the other groups. |
|
667
|
|
|
foreach ($related_groups as $key => $this_group) { |
|
668
|
|
|
$text .= "!group-$key, "; |
|
669
|
|
|
$t_args["!group-$key"] = l($this_group->title, 'node/' . $this_group->nid); |
|
|
|
|
|
|
670
|
|
|
} |
|
671
|
|
|
// Prepare the last group token. |
|
672
|
|
|
$text .= " and !group-$last_group->nid groups."; |
|
673
|
|
|
$t_args["!group-$last_group->nid"] = l($last_group->title, 'node/' . $last_group->nid); |
|
|
|
|
|
|
674
|
|
|
// Prepare the full text with all of the groups and their tokens: |
|
675
|
|
|
return t($text, $t_args); |
|
676
|
|
|
} |
|
677
|
|
|
} |
|
678
|
|
|
|
|
679
|
|
|
function commons_groups_group_submission_message($form, &$form_state) { |
|
|
|
|
|
|
680
|
|
|
if ($form_state['values']['status'] !== 1) { |
|
681
|
|
|
drupal_set_message(t('Thanks for your group submission! This group has entered the moderation queue and will be reviewed shortly.')); |
|
682
|
|
|
} |
|
683
|
|
|
} |
|
684
|
|
|
|
|
685
|
|
|
/** |
|
686
|
|
|
* Default value function for the og_group_ref reference field. |
|
687
|
|
|
* This function is assigned to the field with the default_value_function |
|
688
|
|
|
* property defined in our instances of the og_group_ref field, |
|
689
|
|
|
* which takes place in commons_groups_field_definition(). |
|
690
|
|
|
*/ |
|
691
|
|
|
function commons_groups_entityreference_default_value($entity_type, $entity, $field, $instance, $langcode) { |
|
|
|
|
|
|
692
|
|
|
|
|
693
|
|
|
$items = array(); |
|
694
|
|
|
$field_name = $field['field_name']; |
|
695
|
|
|
|
|
696
|
|
|
if (empty($_GET[$field_name]) || !is_string($_GET[$field_name])) { |
|
697
|
|
|
return $items; |
|
698
|
|
|
} |
|
699
|
|
|
|
|
700
|
|
|
if (empty($instance['settings']['behaviors']['prepopulate']['status'])) { |
|
701
|
|
|
return $items; |
|
702
|
|
|
} |
|
703
|
|
|
|
|
704
|
|
|
$ids = explode(',', $_GET[$field_name]); |
|
705
|
|
|
// Check access to the provided entities. |
|
706
|
|
|
$target_type = $field['settings']['target_type']; |
|
707
|
|
|
entity_load($target_type, $ids); |
|
708
|
|
|
// Remove group nodes hidden by the node access system. |
|
709
|
|
|
foreach ($ids as $target_id) { |
|
710
|
|
|
$target = entity_load_single($target_type, $target_id); |
|
711
|
|
|
if (entity_access('view', $target_type, $target) |
|
712
|
|
|
&& og_is_group_type($target_type, $target->type) |
|
713
|
|
|
&& (og_user_access($target_type, $target_id, "create $entity->type content") || og_user_access($target_type, $target_id, "update any $entity->type content")) |
|
714
|
|
|
) { |
|
715
|
|
|
$items[] = array('target_id' => $target_id); |
|
716
|
|
|
} |
|
717
|
|
|
} |
|
718
|
|
|
return $items; |
|
719
|
|
|
} |
|
720
|
|
|
|
|
721
|
|
|
/** |
|
722
|
|
|
* Implements hook_strongarm_alter(). |
|
723
|
|
|
*/ |
|
724
|
|
|
function commons_groups_strongarm_alter(&$items) { |
|
725
|
|
|
// Expose the Group content type for integration with Commons Radioactivity. |
|
726
|
|
|
if (isset($items['commons_radioactivity_entity_types'])) { |
|
727
|
|
|
$items['commons_radioactivity_entity_types']->value['node']['group'] = 1; |
|
728
|
|
|
} |
|
729
|
|
|
} |
|
730
|
|
|
|
|
731
|
|
|
function commons_groups_default_rules_configuration_alter(&$configs) { |
|
732
|
|
|
// Disable default OG new content notifications. |
|
733
|
|
|
// The language doesn't correspond to Commons' open groups model and we use |
|
734
|
|
|
// commons_follow and commons_follow_notify for new content notifications. |
|
735
|
|
|
if (isset($configs['rules_og_member_active'])) { |
|
736
|
|
|
$configs['rules_og_member_active']->active = FALSE; |
|
737
|
|
|
} |
|
738
|
|
|
} |
|
739
|
|
|
|
|
740
|
|
|
/** |
|
741
|
|
|
* Implements hook_node_presave(). |
|
742
|
|
|
* |
|
743
|
|
|
* When the node's group is private, force the group content to be private. |
|
744
|
|
|
*/ |
|
745
|
|
|
function commons_groups_node_presave($node) { |
|
746
|
|
|
if (!module_exists('og_access')) { |
|
747
|
|
|
return; |
|
748
|
|
|
} |
|
749
|
|
|
|
|
750
|
|
|
$wrapper = entity_metadata_wrapper('node', $node); |
|
751
|
|
|
|
|
752
|
|
|
if (og_is_group('node', $node)) { |
|
753
|
|
|
// Determine whether the group is private according to the subscription |
|
754
|
|
|
// field. |
|
755
|
|
|
$private = $wrapper->field_og_subscribe_settings->value() == 'invitation'; |
|
756
|
|
|
$wrapper->{OG_ACCESS_FIELD}->set((int)$private); |
|
757
|
|
|
return; |
|
758
|
|
|
} |
|
759
|
|
|
|
|
760
|
|
|
if (!og_is_group_content_type('node', $node->type)) { |
|
761
|
|
|
return; |
|
762
|
|
|
} |
|
763
|
|
|
|
|
764
|
|
|
|
|
765
|
|
|
// Check whether any of the groups are private. |
|
766
|
|
|
$private = FALSE; |
|
767
|
|
|
foreach (array_keys(og_get_group_audience_fields('node', $node->type)) as $field) { |
|
768
|
|
|
if (empty($node->$field)) { |
|
769
|
|
|
continue; |
|
770
|
|
|
} |
|
771
|
|
|
|
|
772
|
|
|
foreach ($wrapper->$field as $group_wrapper) { |
|
773
|
|
|
if (empty($group_wrapper->field_og_access_default_value)) { |
|
774
|
|
|
continue; |
|
775
|
|
|
} |
|
776
|
|
|
|
|
777
|
|
|
if ($group_wrapper->field_og_access_default_value->value() == TRUE) { |
|
778
|
|
|
// Once a private group was found, there's no need to continue. |
|
779
|
|
|
$private = TRUE; |
|
780
|
|
|
break 2; |
|
781
|
|
|
} |
|
782
|
|
|
} |
|
783
|
|
|
} |
|
784
|
|
|
|
|
785
|
|
|
if ($private) { |
|
786
|
|
|
$wrapper->{OG_CONTENT_ACCESS_FIELD}->set(OG_CONTENT_ACCESS_PRIVATE); |
|
787
|
|
|
} |
|
788
|
|
|
} |
|
789
|
|
|
|
|
790
|
|
|
/** |
|
791
|
|
|
* Implements hook_node_update(). |
|
792
|
|
|
*/ |
|
793
|
|
|
function commons_groups_node_update($node) { |
|
794
|
|
|
$account = user_load($node->uid); |
|
795
|
|
|
commons_groups_first_contribution($account, $node); |
|
796
|
|
|
|
|
797
|
|
|
if (og_is_group('node', $node)) { |
|
798
|
|
|
commons_groups_set_group_permissions($node); |
|
799
|
|
|
} |
|
800
|
|
|
} |
|
801
|
|
|
|
|
802
|
|
|
/** |
|
803
|
|
|
* Implements hook_node_insert(). |
|
804
|
|
|
*/ |
|
805
|
|
|
function commons_groups_node_insert($node) { |
|
806
|
|
|
$account = user_load($node->uid); |
|
807
|
|
|
commons_groups_first_contribution($account, $node); |
|
808
|
|
|
|
|
809
|
|
|
if (og_is_group('node', $node)) { |
|
810
|
|
|
// When creating a new group, this hook happens before OG creates the |
|
811
|
|
|
// group specific roles. Therefore we create the roles here before altering |
|
812
|
|
|
// them in commons_groups_set_group_permissions(). |
|
813
|
|
|
og_roles_override('node', $node->type, $node->nid); |
|
814
|
|
|
commons_groups_set_group_permissions($node); |
|
815
|
|
|
} |
|
816
|
|
|
} |
|
817
|
|
|
|
|
818
|
|
|
/** |
|
819
|
|
|
* Set the group's permissions according to field_og_subscribe_settings. |
|
820
|
|
|
* |
|
821
|
|
|
* @param $node |
|
822
|
|
|
* A group node. |
|
823
|
|
|
*/ |
|
824
|
|
|
function commons_groups_set_group_permissions($node) { |
|
825
|
|
|
// Avoid updating a group subscription twice on the same request. |
|
826
|
|
|
$updated_nodes = & drupal_static(__FUNCTION__); |
|
827
|
|
|
if (!empty($updated_nodes[$node->nid])) { |
|
828
|
|
|
return; |
|
829
|
|
|
} |
|
830
|
|
|
$updated_nodes[$node->nid] = TRUE; |
|
831
|
|
|
|
|
832
|
|
|
$wrapper = entity_metadata_wrapper('node', $node); |
|
833
|
|
|
$permission = $wrapper->field_og_subscribe_settings->value(); |
|
834
|
|
|
$og_roles = og_roles('node', $node->type, $node->nid); |
|
835
|
|
|
$anon_rid = array_search(OG_ANONYMOUS_ROLE, $og_roles); |
|
836
|
|
|
|
|
837
|
|
|
$permissions = array( |
|
838
|
|
|
'subscribe' => $permission == 'approval', |
|
839
|
|
|
'subscribe without approval' => $permission == 'anyone', |
|
840
|
|
|
); |
|
841
|
|
|
|
|
842
|
|
|
// Check if the permissions needs to be changed. |
|
843
|
|
|
$changed = FALSE; |
|
844
|
|
|
$old_permissions = og_role_permissions(array($anon_rid => OG_ANONYMOUS_ROLE)); |
|
845
|
|
|
foreach ($permissions as $permission => $value) { |
|
846
|
|
|
if (empty($old_permissions[$anon_rid][$permission]) || $old_permissions[$anon_rid][$permission] != $value) { |
|
847
|
|
|
$changed = TRUE; |
|
848
|
|
|
} |
|
849
|
|
|
} |
|
850
|
|
|
|
|
851
|
|
|
// Only change the permissions when neccessary. |
|
852
|
|
|
if ($changed) { |
|
853
|
|
|
og_role_change_permissions($anon_rid, $permissions); |
|
854
|
|
|
} |
|
855
|
|
|
} |
|
856
|
|
|
|
|
857
|
|
|
/** |
|
858
|
|
|
* Helper function to determine whether an entity bundle is considered group |
|
859
|
|
|
* content. |
|
860
|
|
|
* |
|
861
|
|
|
* @param $entity_type |
|
862
|
|
|
* The entity type to check group content settings for. |
|
863
|
|
|
* @param $bundle |
|
864
|
|
|
* The entity bundle to check group content settings for. |
|
865
|
|
|
* |
|
866
|
|
|
* @return boolean |
|
867
|
|
|
* The value of the group content setting if available, FALSE otherwise. |
|
868
|
|
|
*/ |
|
869
|
|
|
function commons_groups_is_group_content($entity_type, $bundle) { |
|
870
|
|
|
$commons_groups_entity_types = commons_groups_get_group_content_entity_types(); |
|
871
|
|
|
|
|
872
|
|
|
return isset($commons_groups_entity_types[$entity_type][$bundle]['is_group_content']) ? $commons_groups_entity_types[$entity_type][$bundle]['is_group_content'] : FALSE; |
|
873
|
|
|
} |
|
874
|
|
|
|
|
875
|
|
|
/** |
|
876
|
|
|
* Returns an array of entity types that are enabled via Commons Groups. |
|
877
|
|
|
*/ |
|
878
|
|
View Code Duplication |
function commons_groups_get_group_content_entity_types($cache = TRUE) { |
|
|
|
|
|
|
879
|
|
|
// Find all Commons Entity integrations. |
|
880
|
|
|
$commons_entity_integrations = commons_entity_integration_info(NULL, $cache); |
|
881
|
|
|
if (empty($commons_entity_integrations)) { |
|
882
|
|
|
return array(); |
|
883
|
|
|
} |
|
884
|
|
|
|
|
885
|
|
|
foreach ($commons_entity_integrations as $entity_type => $integration) { |
|
886
|
|
|
foreach ($integration as $bundle => $options) { |
|
887
|
|
|
if (isset($options['is_group_content']) && $options['is_group_content'] == FALSE) { |
|
888
|
|
|
unset($commons_entity_integrations[$entity_type][$bundle]); |
|
889
|
|
|
} |
|
890
|
|
|
} |
|
891
|
|
|
// If an entity type has no integrations, don't return it. |
|
892
|
|
|
if (empty($commons_entity_integrations[$entity_type])) { |
|
893
|
|
|
unset($commons_entity_integrations[$entity_type]); |
|
894
|
|
|
} |
|
895
|
|
|
} |
|
896
|
|
|
|
|
897
|
|
|
return $commons_entity_integrations; |
|
898
|
|
|
} |
|
899
|
|
|
|
|
900
|
|
|
/** |
|
901
|
|
|
* Returns an array of entity types that are defined as a group. |
|
902
|
|
|
*/ |
|
903
|
|
|
function commons_groups_get_group_types() { |
|
904
|
|
|
// Find all Commons Entity integrations. |
|
905
|
|
|
$commons_groups = array(); |
|
906
|
|
|
$commons_entity_integrations = commons_entity_integration_info(); |
|
907
|
|
|
if (empty($commons_entity_integrations)) { |
|
908
|
|
|
return array(); |
|
909
|
|
|
} |
|
910
|
|
|
|
|
911
|
|
|
foreach ($commons_entity_integrations as $entity_type => $integration) { |
|
912
|
|
|
foreach ($integration as $bundle => $options) { |
|
913
|
|
|
if (isset($options['is_group']) && $options['is_group'] == TRUE) { |
|
914
|
|
|
$commons_groups[$entity_type][$bundle] = $commons_entity_integrations[$entity_type][$bundle]; |
|
915
|
|
|
} |
|
916
|
|
|
} |
|
917
|
|
|
} |
|
918
|
|
|
|
|
919
|
|
|
return $commons_groups; |
|
920
|
|
|
} |
|
921
|
|
|
|
|
922
|
|
|
/** |
|
923
|
|
|
* When a user first creates content within a group, |
|
924
|
|
|
* grant her the contributor role within that group. |
|
925
|
|
|
*/ |
|
926
|
|
|
function commons_groups_first_contribution($account, $node) { |
|
927
|
|
|
// Find the groups that this piece of content belongs to. |
|
928
|
|
|
$groups = og_get_entity_groups('node', $node); |
|
929
|
|
|
// @todo: Make it work also with user-groups. |
|
930
|
|
|
if (!empty($groups['node'])) { |
|
931
|
|
|
$node_groups = array_values($groups['node']); |
|
932
|
|
|
// Find the groups that the node author belongs to. |
|
933
|
|
|
$account_groups = og_get_groups_by_user($account, 'node'); |
|
934
|
|
|
if (!$account_groups) { |
|
935
|
|
|
$account_groups = array(); |
|
936
|
|
|
} |
|
937
|
|
|
// For groups where this user is not already a member, add her to the group. |
|
938
|
|
|
// Anonymous users should never be added to a group automatically |
|
939
|
|
|
if ($account->uid == 0) { |
|
940
|
|
|
return; |
|
941
|
|
|
} |
|
942
|
|
|
$new_groups = array_diff($node_groups, $account_groups); |
|
943
|
|
|
if (!empty($new_groups)) { |
|
944
|
|
|
foreach ($new_groups as $new_group_nid) { |
|
945
|
|
|
og_group('node', $new_group_nid, array('entity' => $account->uid)); |
|
946
|
|
|
} |
|
947
|
|
|
} |
|
948
|
|
|
} |
|
949
|
|
|
} |
|
950
|
|
|
|
|
951
|
|
|
/** |
|
952
|
|
|
* Implements hook_preprocess_node(). |
|
953
|
|
|
*/ |
|
954
|
|
|
function commons_groups_preprocess_node(&$variables) { |
|
955
|
|
|
$variables['user_picture'] = ''; |
|
956
|
|
|
if (variable_get('user_pictures', 0)) { |
|
957
|
|
|
$node = $variables['node']; |
|
958
|
|
|
$account = user_load($node->uid); |
|
959
|
|
|
|
|
960
|
|
|
if (!empty($account->picture)) { |
|
961
|
|
|
// @TODO: Ideally this function would only be passed file objects, but |
|
962
|
|
|
// since there's a lot of legacy code that JOINs the {users} table to |
|
963
|
|
|
// {node} or {comments} and passes the results into this function if we |
|
964
|
|
|
// a numeric value in the picture field we'll assume it's a file id |
|
965
|
|
|
// and load it for them. Once we've got user_load_multiple() and |
|
966
|
|
|
// comment_load_multiple() functions the user module will be able to load |
|
967
|
|
|
// the picture files in mass during the object's load process. |
|
968
|
|
|
if (is_numeric($account->picture)) { |
|
969
|
|
|
$account->picture = file_load($account->picture); |
|
970
|
|
|
} |
|
971
|
|
|
if (!empty($account->picture->uri)) { |
|
972
|
|
|
$filepath = $account->picture->uri; |
|
973
|
|
|
} |
|
974
|
|
|
} |
|
975
|
|
|
elseif (variable_get('user_picture_default', '')) { |
|
976
|
|
|
$filepath = variable_get('user_picture_default', ''); |
|
977
|
|
|
} |
|
978
|
|
|
|
|
979
|
|
|
if (isset($filepath)) { |
|
980
|
|
|
if (module_exists('image') && file_valid_uri($filepath)) { |
|
981
|
|
|
$alt = t("@user's picture", array('@user' => format_username($account))); |
|
982
|
|
|
|
|
983
|
|
|
$render = array( |
|
984
|
|
|
'#theme' => 'image_formatter', |
|
985
|
|
|
'#image_style' => '50x50', |
|
986
|
|
|
'#item' => array( |
|
987
|
|
|
'uri' => $filepath, |
|
988
|
|
|
'alt' => $alt, |
|
989
|
|
|
), |
|
990
|
|
|
'#path' => array( |
|
991
|
|
|
'path' => 'user/' . $account->uid, |
|
992
|
|
|
'options' => array( |
|
993
|
|
|
'attributes' => array( |
|
994
|
|
|
'title' => t("View @user's profile.", array('@user' => format_username($account))), |
|
995
|
|
|
'class' => array('user-picture'), |
|
996
|
|
|
), |
|
997
|
|
|
), |
|
998
|
|
|
), |
|
999
|
|
|
); |
|
1000
|
|
|
|
|
1001
|
|
|
// Use a unique image style for user pictures in post information. |
|
1002
|
|
|
$variables['user_picture'] = drupal_render($render); |
|
1003
|
|
|
} |
|
1004
|
|
|
} |
|
1005
|
|
|
} |
|
1006
|
|
|
} |
|
1007
|
|
|
|
|
1008
|
|
|
/** |
|
1009
|
|
|
* Implements hook_preprocess_views_view_list(). |
|
1010
|
|
|
*/ |
|
1011
|
|
|
function commons_groups_preprocess_views_view_list(&$variables, $hook) { |
|
|
|
|
|
|
1012
|
|
|
// Change the displayed role name in the group contributors block to |
|
1013
|
|
|
// "Organizers". |
|
1014
|
|
|
if ($variables['view']->name == 'commons_contributors_group' && !empty($variables['title']) && $variables['title'] == 'administrator member') { |
|
1015
|
|
|
$variables['title'] = t('Organizers'); |
|
1016
|
|
|
} |
|
1017
|
|
|
} |
|
1018
|
|
|
|
|
1019
|
|
|
/** |
|
1020
|
|
|
* Implements hook_field_access(). |
|
1021
|
|
|
*/ |
|
1022
|
|
|
function commons_groups_field_access($op, $field, $entity_type, $entity, $account) { |
|
|
|
|
|
|
1023
|
|
|
$field_name = $field['field_name']; |
|
1024
|
|
|
switch ($field_name) { |
|
1025
|
|
|
case 'og_roles_permissions': |
|
1026
|
|
|
return FALSE; |
|
1027
|
|
|
|
|
1028
|
|
|
case 'field_og_access_default_value': |
|
1029
|
|
|
return $op == 'edit' && module_exists('og_access'); |
|
1030
|
|
|
|
|
1031
|
|
|
case 'field_og_subscribe_settings': |
|
1032
|
|
|
return $op == 'edit'; |
|
1033
|
|
|
} |
|
1034
|
|
|
|
|
1035
|
|
|
if (module_exists('og_access') && in_array($field_name, array(OG_CONTENT_ACCESS_FIELD, OG_ACCESS_FIELD))) { |
|
1036
|
|
|
return FALSE; |
|
1037
|
|
|
} |
|
1038
|
|
|
} |
|
1039
|
|
|
|
|
1040
|
|
|
/** |
|
1041
|
|
|
* Implements hook_field_formatter_info(). |
|
1042
|
|
|
*/ |
|
1043
|
|
|
function commons_groups_field_formatter_info() { |
|
1044
|
|
|
return array( |
|
1045
|
|
|
'commons_groups_group_subscribe' => array( |
|
1046
|
|
|
'label' => t('Commons groups subscribe link'), |
|
1047
|
|
|
'field types' => array('list_boolean'), |
|
1048
|
|
|
'settings' => array( |
|
1049
|
|
|
'field_name' => FALSE, |
|
1050
|
|
|
), |
|
1051
|
|
|
), |
|
1052
|
|
|
); |
|
1053
|
|
|
} |
|
1054
|
|
|
|
|
1055
|
|
|
/** |
|
1056
|
|
|
* Implements hook_field_formatter_view(). |
|
1057
|
|
|
*/ |
|
1058
|
|
|
function commons_groups_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { |
|
|
|
|
|
|
1059
|
|
|
global $user; |
|
1060
|
|
|
$account = clone $user; |
|
1061
|
|
|
|
|
1062
|
|
|
if ($display['type'] != 'commons_groups_group_subscribe') { |
|
1063
|
|
|
return; |
|
1064
|
|
|
} |
|
1065
|
|
|
|
|
1066
|
|
|
if (!og_is_group($entity_type, $entity)) { |
|
1067
|
|
|
return; |
|
1068
|
|
|
} |
|
1069
|
|
|
|
|
1070
|
|
|
if (!empty($entity->uid) && ($entity->uid == $account->uid)) { |
|
1071
|
|
|
// User is the group manager. |
|
1072
|
|
|
$element[0] = array('#markup' => t('You are the group manager')); |
|
|
|
|
|
|
1073
|
|
|
return $element; |
|
1074
|
|
|
} |
|
1075
|
|
|
|
|
1076
|
|
|
list($id, , $bundle) = entity_extract_ids($entity_type, $entity); |
|
1077
|
|
|
|
|
1078
|
|
|
// The user has a pending membership request. Let her know that |
|
1079
|
|
|
// her request is pending review. |
|
1080
|
|
|
if (og_is_member($entity_type, $id, 'user', $account, array(OG_STATE_PENDING))) { |
|
1081
|
|
|
$element[0] = array('#markup' => '<div class="subscription-type">' . t('Your membership request is pending review by a group organizer.') . '</div>'); |
|
|
|
|
|
|
1082
|
|
|
return $element; |
|
1083
|
|
|
} |
|
1084
|
|
|
// If user is blocked, they should not be able to apply for membership. |
|
1085
|
|
|
if (og_is_member($entity_type, $id, 'user', $account, array(OG_STATE_BLOCKED))) { |
|
1086
|
|
|
return; |
|
1087
|
|
|
} |
|
1088
|
|
|
if (og_is_member($entity_type, $id, 'user', $account)) { |
|
1089
|
|
|
// The user has an active membership. |
|
1090
|
|
|
if (og_user_access($entity_type, $id, 'unsubscribe', $account)) { |
|
1091
|
|
|
// The user has the permission to unsubscribe himself, |
|
1092
|
|
|
// otherwise don't display a "Leave" link since the user can't leave |
|
1093
|
|
|
// anyways. |
|
1094
|
|
|
// For groups where anyone can contribute without joining, don't display |
|
1095
|
|
|
// a "Leave" link since users never went through |
|
1096
|
|
|
// the separate step of joining. |
|
1097
|
|
|
if (og_is_member($entity_type, $id, 'user', $account, array(OG_STATE_ACTIVE)) && $entity->field_og_subscribe_settings[LANGUAGE_NONE][0]['value'] != 'anyone') { |
|
1098
|
|
|
$links['title'] = t('Leave group'); |
|
|
|
|
|
|
1099
|
|
|
$links['href'] = "group/$entity_type/$id/unsubscribe"; |
|
1100
|
|
|
} |
|
1101
|
|
|
} |
|
1102
|
|
|
} |
|
1103
|
|
|
else { |
|
1104
|
|
|
// Check if user can subscribe to the field. |
|
1105
|
|
View Code Duplication |
if (empty($settings['field_name']) && $audience_field_name = og_get_best_group_audience_field('user', $account, $entity_type, $bundle)) { |
|
|
|
|
|
|
1106
|
|
|
$settings['field_name'] = $audience_field_name; |
|
|
|
|
|
|
1107
|
|
|
} |
|
1108
|
|
|
if (!$settings['field_name']) { |
|
1109
|
|
|
return; |
|
1110
|
|
|
} |
|
1111
|
|
|
|
|
1112
|
|
|
$field_info = field_info_field($settings['field_name']); |
|
1113
|
|
|
|
|
1114
|
|
|
// Check if entity is referencable. |
|
1115
|
|
|
if ($field_info['settings']['target_type'] != $entity_type) { |
|
1116
|
|
|
// Group type doesn't match. |
|
1117
|
|
|
return; |
|
1118
|
|
|
} |
|
1119
|
|
View Code Duplication |
if (!empty($field_info['settings']['handler_settings']['target_bundles']) && !in_array($bundle, $field_info['settings']['handler_settings']['target_bundles'])) { |
|
|
|
|
|
|
1120
|
|
|
// Bundles don't match. |
|
1121
|
|
|
return; |
|
1122
|
|
|
} |
|
1123
|
|
|
|
|
1124
|
|
View Code Duplication |
if (!og_check_field_cardinality('user', $account, $settings['field_name'])) { |
|
|
|
|
|
|
1125
|
|
|
$element[0] = array('#markup' => format_plural($field_info['cardinality'], 'You are already registered to another group', 'You are already registered to @count groups')); |
|
|
|
|
|
|
1126
|
|
|
return $element; |
|
1127
|
|
|
} |
|
1128
|
|
|
|
|
1129
|
|
|
$url = "group/$entity_type/$id/subscribe"; |
|
1130
|
|
|
if ($settings['field_name']) { |
|
1131
|
|
|
$url .= '/' . $settings['field_name']; |
|
1132
|
|
|
} |
|
1133
|
|
|
// Set the needs update hook if we end up with a group call that is missing |
|
1134
|
|
|
// the subscribe settings. We also check the variable first, because we |
|
1135
|
|
|
// don't want to reset the variable cache if we don't have to. |
|
1136
|
|
|
// See https://drupal.org/node/2059857#comment-7733465 for more info. |
|
1137
|
|
|
if (empty($entity->field_og_subscribe_settings)) { |
|
1138
|
|
|
if (!variable_get('commons_groups_needs_update', FALSE)) { |
|
1139
|
|
|
variable_set('commons_groups_needs_update', TRUE); |
|
1140
|
|
|
} |
|
1141
|
|
|
} |
|
1142
|
|
|
// Don't display join link on public groups. |
|
1143
|
|
|
else { |
|
1144
|
|
|
if ($entity->field_og_subscribe_settings[LANGUAGE_NONE][0]['value'] != 'anyone') { |
|
1145
|
|
|
if ($entity->field_og_subscribe_settings[LANGUAGE_NONE][0]['value'] == 'approval') { |
|
1146
|
|
|
$subscription_type = t('Moderated group'); |
|
1147
|
|
|
$links['title'] = t('Join group'); |
|
|
|
|
|
|
1148
|
|
|
if ($account->uid) { |
|
1149
|
|
|
$links['href'] = $url; |
|
1150
|
|
|
} |
|
1151
|
|
|
else { |
|
1152
|
|
|
$links['href'] = 'user/login'; |
|
1153
|
|
|
$links['options'] = array('query' => array('destination' => $url)); |
|
1154
|
|
|
} |
|
1155
|
|
|
} |
|
1156
|
|
|
else { |
|
1157
|
|
|
$element[0] = array('#markup' => '<div class="subscription-type">' . t('Invite-only group') . '</div>'); |
|
|
|
|
|
|
1158
|
|
|
return $element; |
|
1159
|
|
|
} |
|
1160
|
|
|
} |
|
1161
|
|
|
} |
|
1162
|
|
|
} |
|
1163
|
|
|
if (!empty($links['title'])) { |
|
1164
|
|
|
$links += array('options' => array()); |
|
1165
|
|
|
$element[0] = array( |
|
|
|
|
|
|
1166
|
|
|
'#type' => 'link', |
|
1167
|
|
|
'#title' => $links['title'], |
|
1168
|
|
|
'#href' => $links['href'], |
|
1169
|
|
|
'#options' => $links['options'], |
|
1170
|
|
|
); |
|
1171
|
|
|
|
|
1172
|
|
|
if (!empty($subscription_type)) { |
|
1173
|
|
|
$element[0]['#prefix'] = '<div class="subscription-type">' . $subscription_type . '</div>'; |
|
1174
|
|
|
} |
|
1175
|
|
|
|
|
1176
|
|
|
return $element; |
|
1177
|
|
|
} |
|
1178
|
|
|
} |
|
1179
|
|
|
|
|
1180
|
|
|
/** |
|
1181
|
|
|
* Implements hook_views_pre_render(). |
|
1182
|
|
|
*/ |
|
1183
|
|
View Code Duplication |
function commons_groups_views_pre_render(&$view) { |
|
|
|
|
|
|
1184
|
|
|
// Improve the browsing widget empty text when displayed outside of a group. |
|
1185
|
|
|
// TODO: Enable og_context and check group context instead of looking for an |
|
1186
|
|
|
// empty first argument. |
|
1187
|
|
|
if (empty($view->args[0]) && $view->name == 'commons_bw_all') { |
|
1188
|
|
|
$view->display_handler->handlers['empty']['area']->options['content'] = t('Nobody has posted yet.'); |
|
1189
|
|
|
} |
|
1190
|
|
|
} |
|
1191
|
|
|
|
|
1192
|
|
|
/** |
|
1193
|
|
|
* Special Commons implementation of hook_features_rebuild(). |
|
1194
|
|
|
* |
|
1195
|
|
|
* By default, reverting og permissions only occurs on the default rid, which is |
|
1196
|
|
|
* 0. All groups already created will not see the new permissions. |
|
1197
|
|
|
* |
|
1198
|
|
|
* As an alternative, this function iterates through all of the groups and sets |
|
1199
|
|
|
* default permissions and update the permissions map. |
|
1200
|
|
|
* |
|
1201
|
|
|
* @param string $module |
|
1202
|
|
|
* The modules whose default user permissions should be rebuild. |
|
1203
|
|
|
*/ |
|
1204
|
|
|
function commons_groups_features_permission_rebuild($module, $gid) { |
|
1205
|
|
|
module_load_include('features.inc', 'og', '/includes/og_features_role'); |
|
1206
|
|
|
|
|
1207
|
|
|
if ($defaults = features_get_default('og_features_permission', $module)) { |
|
1208
|
|
|
// Make sure the list of available group types is up to date, especially |
|
1209
|
|
|
// when installing multiple features at once, for example from an install |
|
1210
|
|
|
// profile or via drush. |
|
1211
|
|
|
drupal_static_reset(); |
|
1212
|
|
|
|
|
1213
|
|
|
$grant = array(); |
|
1214
|
|
|
$revoke = array(); |
|
1215
|
|
|
|
|
1216
|
|
|
foreach ($defaults as $key => $details) { |
|
1217
|
|
|
list($group_type, $bundle, $perm) = explode(':', $key); |
|
1218
|
|
|
|
|
1219
|
|
|
// Make sure the role exists for this entity. |
|
1220
|
|
|
foreach ($details['roles'] as $role) { |
|
1221
|
|
|
$bundle_role = _og_features_role_exists($role, $group_type, $bundle); |
|
1222
|
|
|
if (empty($bundle_role)) { |
|
1223
|
|
|
og_role_save(og_role_create($role, $group_type, $gid, $bundle)); |
|
1224
|
|
|
} |
|
1225
|
|
|
} |
|
1226
|
|
|
|
|
1227
|
|
|
$roles = og_roles($group_type, $bundle, $gid); |
|
1228
|
|
|
foreach ($roles as $rid => $rolename) { |
|
1229
|
|
|
if (in_array($rolename, $details['roles'])) { |
|
1230
|
|
|
$grant[$rid][] = $perm; |
|
1231
|
|
|
} |
|
1232
|
|
|
else { |
|
1233
|
|
|
$revoke[$rid][] = $perm; |
|
1234
|
|
|
} |
|
1235
|
|
|
} |
|
1236
|
|
|
} |
|
1237
|
|
|
|
|
1238
|
|
|
if (!empty($grant)) { |
|
1239
|
|
|
foreach ($grant as $rid => $permissions) { |
|
1240
|
|
|
og_role_grant_permissions($rid, $permissions); |
|
1241
|
|
|
} |
|
1242
|
|
|
} |
|
1243
|
|
|
|
|
1244
|
|
|
if (!empty($revoke)) { |
|
1245
|
|
|
foreach ($revoke as $rid => $permissions) { |
|
1246
|
|
|
og_role_revoke_permissions($rid, $permissions); |
|
1247
|
|
|
} |
|
1248
|
|
|
} |
|
1249
|
|
|
} |
|
1250
|
|
|
} |
|
1251
|
|
|
|
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.