/[drupal]/contributions/modules/forum_access/forum_access.admin.inc
ViewVC logotype

Contents of /contributions/modules/forum_access/forum_access.admin.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.26 - (show annotations) (download) (as text)
Sun Oct 4 21:12:58 2009 UTC (7 weeks, 1 day ago) by salvis
Branch: MAIN
Changes since 1.25: +6 -6 lines
File MIME type: text/x-php
Fix some trailing spaces (no functional change).
1 <?php
2 // $Id: forum_access.admin.inc,v 1.25 2009/09/20 01:09:20 salvis Exp $
3
4 /**
5 * @file forum_access.admin.inc
6 *
7 * Include file for forum_access.module, containing (sub-)page handling
8 * (form_alter) and batch code.
9 *
10 */
11
12 /**
13 * Rewrite the forum administration page with our new access rules.
14 */
15 function _forum_access_forum_form(&$form, &$form_state, $is_container) {
16 $tid = (isset($form['tid']['#value']) ? $form['tid']['#value'] : NULL);
17
18 $roles = array();
19 $result = db_query("SELECT r.rid, r.name FROM {role} r ORDER BY r.name");
20 while ($obj = db_fetch_object($result)) {
21 $roles[$obj->rid] = check_plain($obj->name);
22 }
23
24 if (isset($tid)) { // edit
25 $template_tid = variable_get('forum_access_default_template_tid', 0);
26 $settings = _forum_access_get_settings($tid);
27 }
28 else { // create
29 $template_tid = variable_get('forum_access_new_template_tid', NULL);
30 $settings = _forum_access_get_settings($template_tid);
31 }
32 $fa_priority = $settings['priority'];
33
34 $form['forum_access'] = array(
35 '#type' => 'fieldset',
36 '#title' => t('Access control'),
37 '#collapsible' => TRUE,
38 '#tree' => TRUE,
39 );
40
41 $tr = 't';
42 $variables = array(
43 '!access_content' => '<em>'. l($tr('access content'), 'admin/user/permissions', array('fragment' => 'module-node', 'html' => TRUE)). '</em>',
44 '!access_comments' => '<em>'. l($tr('access comments'), 'admin/user/permissions', array('fragment' => 'module-comment', 'html' => TRUE)). '</em>',
45 '!create_forum_topics' => '<em>'. l($tr('create forum topics'), 'admin/user/permissions', array('fragment' => 'module-forum', 'html' => TRUE)). '</em>',
46 '!post_comments' => '<em>'. l($tr('post comments'), 'admin/user/permissions', array('fragment' => 'module-comment', 'html' => TRUE)). '</em>',
47 '!post_comments_without_approval' => '<em>'. l($tr('post comments without approval'), 'admin/user/permissions', array('fragment' => 'module-comment', 'html' => TRUE)). '</em>',
48 '!edit_own_forum_topics' => '<em>'. l($tr('edit own forum topics'), 'admin/user/permissions', array('fragment' => 'module-forum', 'html' => TRUE)). '</em>',
49 '!edit_any_forum_topics' => '<em>'. l($tr('edit any forum topics'), 'admin/user/permissions', array('fragment' => 'module-forum', 'html' => TRUE)). '</em>',
50 '!delete_own_forum_topics' => '<em>'. l($tr('delete own forum topics'), 'admin/user/permissions', array('fragment' => 'module-forum', 'html' => TRUE)). '</em>',
51 '!delete_any_forum_topics' => '<em>'. l($tr('delete any forum topics'), 'admin/user/permissions', array('fragment' => 'module-forum', 'html' => TRUE)). '</em>',
52 '!administer_comments' => '<em>'. l($tr('administer comments'), 'admin/user/permissions', array('fragment' => 'module-comment', 'html' => TRUE)). '</em>',
53 '!administer_forums' => '<em>'. l($tr('administer forums'), 'admin/user/permissions', array('fragment' => 'module-forum', 'html' => TRUE)). '</em>',
54 '!administer_nodes' => '<em>'. l($tr('administer nodes'), 'admin/user/permissions', array('fragment' => 'module-node', 'html' => TRUE)). '</em>',
55 );
56 if (!$is_container) {
57 $form['forum_access']['permissions'] = array(
58 '#type' => 'fieldset',
59 '#title' => $tr('Permissions information'),
60 '#collapsible' => TRUE,
61 '#collapsed' => TRUE,
62 );
63 $form['forum_access']['permissions'][] = array(
64 '#type' => 'markup',
65 '#value' => '<div>'. t('Note that users need') .'<ul style="margin-top: 0"><li>'.
66 t('the !access_content and !access_comments permissions <strong>AND <em>View</em></strong> to be able to see this forum and its content at all,', $variables) .'</li><li>'.
67 t('the !create_forum_topics (and similar) permissions <strong>AND <em>Post</em></strong> to be able to create forum content, and', $variables) .'</li><li>'.
68 t('the !post_comments and (probably) !post_comments_without_approval permission <!TAG>AND <em>Post</em></!TAG> to be able to post comments/replies;', $variables + array('!TAG' => (variable_get('forum_access_D5_legacy_mode', FALSE) ? 'del title="'. t('Drupal 5 legacy mode') .'"' : 'strong'))) .'</li><li>'.
69 t('the !edit_own_forum_topics or !edit_any_forum_topics (and similar) permissions (<strong>OR <em>Edit</em></strong>) can be added if desired, <strong>plus</strong>', $variables) .'</li><li>'.
70 t('the !delete_own_forum_topics or !delete_any_forum_topics (and similar) permissions (<strong>OR <em>Delete</em></strong>) if desired;', $variables) .'</li><li>'.
71 t('the !administer_comments (global!) permission <strong>OR <em>Edit</em>/<em>Delete</em></strong> to be able to edit/delete comments;', $variables) .'</li><li>'.
72 t('the !administer_forums permission <strong>AND <em>View</em></strong> to be able to administer forums (and change access!).', $variables) .'</li></ul>'.
73 t('Furthermore note that content which is not published is treated in a different way by Drupal: it can be viewed only by its author or by users with the !administer_nodes permission. Unpublished comments and replies are accessible to users with <strong><em>Edit</em> OR <em>Delete</em></strong>, <strong>OR</strong> with the !administer_comments permission, but they are never counted on the forum page.', $variables) .'</div>',
74 );
75 }
76
77 // Load a template:
78 $vid = variable_get('forum_nav_vocabulary', '');
79 $form['forum_access']['template'] = array(
80 '#type' => 'fieldset',
81 '#title' => $tr('Template'),
82 '#collapsible' => TRUE,
83 '#collapsed' => empty($template_tid),
84 );
85 $form['forum_access']['template']['taxonomy'][$vid] = taxonomy_form($vid, array($template_tid), '');
86 $form['forum_access']['template']['taxonomy'][$vid]['#description'] = t("Select a forum and click !Load to retrieve that forum's settings as a starting point for this forum or container.", array('!Load' => '['. t('Load') .']'));
87 $form['forum_access']['template']['load_button'] = array(
88 '#type' => 'button',
89 '#name' => 'load_template',
90 '#value' => t('Load'),
91 '#submit' => FALSE,
92 );
93 $form['forum_access']['template']['template_tid'] = array(
94 '#type' => 'value',
95 '#value' => NULL,
96 );
97 $form['forum_access']['template']['select_by_default'] = array(
98 '#type' => 'checkbox',
99 '#title' => t('Remember this selection.'),
100 '#default_value' => FALSE,
101 );
102 $form['forum_access']['template']['load_for_new'] = array(
103 '#type' => 'checkbox',
104 '#title' => t("Use the selected forum's settings as defaults for new forums and containers."),
105 '#default_value' => FALSE,
106 );
107 $form['forum_access']['#after_build'][] = '_forum_access_forum_form_after_build';
108
109 // Column titles:
110 $form['forum_access']['headers']['view'] = array(
111 '#type' => 'item',
112 '#prefix' => '<div class="forum-access-div">',
113 '#title' => ($is_container ? t('View this container') : t('View this forum')),
114 '#suffix' => '</div>',
115 );
116 $forum_vocabulary = taxonomy_vocabulary_load(variable_get('forum_nav_vocabulary', ''));
117 $form['forum_access']['headers']['create'] = array(
118 '#type' => 'item',
119 '#prefix' => '<div class="forum-access-div" id="container">',
120 '#title' => t('See this container in the %Forums selection list', array('%Forums' => $forum_vocabulary->name)),
121 '#suffix' => '</div>',
122 );
123 if (!$is_container) {
124 $form['forum_access']['headers']['create'] = array( // overwrite!
125 '#type' => 'item',
126 '#prefix' => '<div class="forum-access-div">',
127 '#title' => t('Post in this forum'),
128 '#suffix' => '</div>',
129 );
130 $form['forum_access']['headers']['update'] = array(
131 '#type' => 'item',
132 '#prefix' => '<div class="forum-access-div">',
133 '#title' => t('Edit posts'),
134 '#suffix' => '</div>',
135 );
136 $form['forum_access']['headers']['delete'] = array(
137 '#type' => 'item',
138 '#prefix' => '<div class="forum-access-div">',
139 '#title' => t('Delete posts'),
140 '#suffix' => '</div>',
141 );
142 }
143 $form['forum_access']['headers']['clearer'] = array(
144 '#value' => '<div class="forum-access-clearer"></div>',
145 );
146
147 // Column content (checkboxes):
148 $form['forum_access']['view'] = array(
149 '#type' => 'checkboxes',
150 '#prefix' => '<div class="forum-access-div">',
151 '#suffix' => '</div>',
152 '#options' => $roles,
153 '#default_value' => $settings['view'],
154 '#process' => array('expand_checkboxes', '_forum_access_forum_form_disable_checkboxes'),
155 );
156 $form['forum_access']['create'] = array(
157 '#type' => 'checkboxes',
158 '#prefix' => '<div class="forum-access-div">',
159 '#suffix' => '</div>',
160 '#options' => $roles,
161 '#default_value' => $settings['create'],
162 '#process' => array('expand_checkboxes', '_forum_access_forum_form_disable_checkboxes'),
163 );
164 if (!$is_container) {
165 $form['forum_access']['update'] = array(
166 '#type' => 'checkboxes',
167 '#prefix' => '<div class="forum-access-div">',
168 '#suffix' => '</div>',
169 '#options' => $roles,
170 '#default_value' => $settings['update'],
171 '#process' => array('expand_checkboxes', '_forum_access_forum_form_disable_checkboxes'),
172 );
173 $form['forum_access']['delete'] = array(
174 '#type' => 'checkboxes',
175 '#prefix' => '<div class="forum-access-div">',
176 '#suffix' => '</div>',
177 '#options' => $roles,
178 '#default_value' => $settings['delete'],
179 '#process' => array('expand_checkboxes', '_forum_access_forum_form_disable_checkboxes'),
180 );
181 }
182 $form['forum_access']['clearer'] = array(
183 '#type' => 'item',
184 '#prefix' => '<div class="forum-access-clearer">',
185 '#suffix' => '</div>',
186 '#description' => t('For explanations of special cases, hover your mouse over role names.'),
187 );
188 if ($is_container) {
189 $form['forum_access']['container_note'] = array(
190 '#type' => 'item',
191 '#description' => t('Users who can see any forum or container within this one should get the <strong><em>View</em></strong> grant. <br /> Users who can post to a forum within this container should get the <strong><em>See</em></strong> grant, so that this forum appears in the proper context in the selection list.', $variables),
192 );
193 }
194
195 drupal_add_css(drupal_get_path('module', 'forum_access') .'/forum_access.css');
196
197 // Find our moderator ACL:
198 if (isset($tid)) { // edit, not new
199 $acl_id = db_result(db_query("SELECT acl_id from {acl} WHERE module = 'forum_access' AND name = '%d'", $tid));
200 if (!$acl_id) { // create one
201 $acl_id = acl_create_new_acl('forum_access', $tid);
202 // update every existing node in this forum to use this acl.
203 $result = db_query("SELECT nid FROM {term_node} WHERE tid = %d", $tid);
204 while ($node = db_fetch_object($result)) {
205 // all privs to this ACL.
206 acl_node_add_acl($node->nid, $acl_id, 1, 1, 1);
207 }
208 }
209 $form['forum_access']['acl'] = acl_edit_form($acl_id, t('Moderators'));
210 $form['forum_access']['acl'][] = array(
211 '#type' => 'markup',
212 '#value' => '<div>'. t('Moderators receive all grants above.') .'</div>',
213 '#weight' => -1,
214 );
215 $form['forum_access']['acl']['note'] = array(
216 '#type' => 'markup',
217 '#value' => '<div>'. t('Note: Changes to moderators are not saved until you click [!Save] below.', array('!Save' => $tr('Save'))) .'</div>',
218 );
219 $form['forum_access']['acl']['#after_build'][] = '_forum_access_forum_form_after_build_acl0';
220 $form['forum_access']['acl']['#after_build'] = array_reverse($form['forum_access']['acl']['#after_build']);
221 $form['forum_access']['acl']['#after_build'][] = '_forum_access_forum_form_after_build_acl2';
222 }
223
224 foreach (module_implements('node_access_records') as $module) {
225 $na_modules[$module] = $module;
226 }
227 unset($na_modules['forum_access']);
228 unset($na_modules['acl']);
229 if (count($na_modules) && !$is_container) {
230 $form['forum_access']['interference'] = array(
231 '#type' => 'fieldset',
232 '#title' => t('Module interference'),
233 '#collapsible' => TRUE,
234 );
235 $variables = array(
236 '%content_type' => node_get_types('name', 'forum'),
237 '!Forum_Access' => 'Forum Access',
238 '!Content_Access' => l('Content Access', 'http://drupal.org/project/content_access'),
239 '@Content_Access' => 'Content Access',
240 '!ACL' => 'ACL',
241 '!module_list' => '<ul><li>'. implode($na_modules, '</li><li>') .'</li></ul>',
242 );
243 $form['forum_access']['interference'][] = array(
244 '#type' => 'item',
245 '#value' => '<p>'. t("Besides !Forum_Access (and !ACL) you have installed the following node access module(s): !module_list The grants of every module are combined for each node. Access can only be granted, not removed &mdash; if a certain module grants a permission, the other(s) cannot deny it.", $variables) .'</p>',
246 '#description' => t('Forums can contain other content types besides %content_type; !Forum_Access will contribute the grants defined above to every node in this forum, but other node access control modules may also contribute their grants, especially to nodes of types other than %content_type.', $variables),
247 );
248
249 if (module_exists('content_access')) {
250 $ca_settings = variable_get('content_access_settings', array());
251 foreach (array('view', 'update', 'delete', 'per_node') as $type) {
252 $value = content_access_get_settings($type, 'forum');
253 if (!empty($value)) {
254 $ca_interferes = TRUE;
255 }
256 }
257 $ca_priority = content_access_get_settings('priority', 'forum');
258 $is_conflict = $ca_priority >= $fa_priority && !empty($ca_interferes) || $ca_priority > $fa_priority;
259 $variables += array(
260 '!link' => l(t('@Content_Access configuration for the %content_type type', $variables), 'admin/content/node-type/forum/access', array('html' => TRUE)),
261 '%Advanced' => $tr('Advanced'),
262 );
263 $specifically = ($ca_priority == $fa_priority ? t('Specifically, any grants given by !Content_Access cannot be taken back by !Forum_Access.', $variables) : '');
264 if ($is_conflict) {
265 $form['forum_access']['interference']['by_content_access'] = array(
266 '#type' => 'fieldset',
267 '#title' => 'Content Access',
268 '#collapsible' => FALSE,
269 '#attributes' => array('class' => 'error'),
270 );
271 $form['forum_access']['interference']['by_content_access'][] = array(
272 '#value' => '<div>'. t('You have set the !Content_Access module to control access to content of type %content_type&mdash;this can interfere with proper operation of !Forum_Access!', $variables) ." $specifically</div>",
273 );
274 if ($ca_priority == $fa_priority) {
275 $form['forum_access']['interference']['by_content_access'][] = array(
276 '#value' => '<div>'. t("Unless you really know what you're doing, we recommend that you go to the !link page and clear all checkboxes. This will instruct @Content_Access to leave the %content_type nodes alone. However, if you put nodes of other content types into forums as well, then these content types will continue to have this problem.", $variables) .'</div>',
277 );
278 }
279 else {
280 $form['forum_access']['interference']['by_content_access'][] = array(
281 '#value' => '<div>'. t("The priority of @Content_Access ($ca_priority) is higher than the priority of !Forum_Access ($fa_priority), which means the latter is <strong>completely disabled</strong> for the %content_type type! Unless you really know what you're doing, we recommend that you go to the !link page, change the priority (under %Advanced) to 0, and clear all checkboxes.", $variables) .'</div>',
282 );
283 }
284 $form['forum_access']['interference']['by_content_access'][] = array(
285 '#value' => '<div>'. t("Alternatively, you can give !Forum_Access priority over @Content_Access by either raising the priority of !Forum_Access in every forum above the priority of @Content_Access, or by lowering the priority of @Content_Access for the content types in question below the priority of !Forum_Access.", $variables) .'</div>',
286 );
287 }
288 else {
289 $form['forum_access']['interference'][] = array(
290 '#value' => '<p>'. t('Note: You have installed the !Content_Access module, which has the capability to grant access to content that would otherwise be protected by !Forum_Access. Be careful when configuring @Content_Access!', $variables) .'</p>',
291 );
292 }
293 }
294
295 $form['forum_access']['interference']['advanced'] = array(
296 '#type' => 'fieldset',
297 '#title' => t('Advanced'),
298 '#collapsible' => TRUE,
299 '#collapsed' => !($fa_priority != 0),
300 );
301 $form['forum_access']['interference']['advanced']['priority'] = array(
302 '#type' => 'weight',
303 '#title' => t('Priority of !Forum_Access node grants in this forum', $variables),
304 '#default_value' => $fa_priority,
305 '#description' => t("If you have no other node access control modules installed, you should leave this at the default 0. <br /> Otherwise you can raise or lower the priority of !Forum_Access' grants. Out of all the grants contributed to a node, only those with the highest priority are used, and all others are discarded.", $variables),
306 );
307 }
308
309 if (!$is_container) {
310 $variables = array(
311 '!Forum_Access' => l('Forum Access', 'http://drupal.org/project/forum_access'),
312 '!ACL' => l('ACL', 'http://drupal.org/project/acl'),
313 '%Module_interference' => t('Module interference'),
314 '!Forum_Access-dev' => l('Forum&nbsp;Access&nbsp;6.x-1.x-dev', 'http://drupal.org/node/96795', array('html' => TRUE)),
315 '!ACL-dev' => l('ACL&nbsp;6.x-1.x-dev', 'http://drupal.org/node/96794', array('html' => TRUE)),
316 '%devel_node_access' => 'devel_node_access',
317 '!Devel' => l('Devel', 'http://drupal.org/project/devel'),
318 '!DNA' => 'DNA',
319 '!debug_mode' => l('debug mode', 'admin/settings/devel', array('fragment' => 'edit-devel-node-access-debug-mode')),
320 '!dna_summary' => l('devel/node_access/summary', 'devel/node_access/summary'),
321 '!Rebuild_permissions' => '['. $tr('Rebuild permissions') .']',
322 '!Post_settings_link' => l('admin/content/node-settings', 'admin/content/node-settings'),
323 '!Forum_Access_' => l('Forum Access', 'http://drupal.org/project/issues/forum_access'),
324 '!ACL_' => l('ACL', 'http://drupal.org/project/issues/acl'),
325 );
326 $form['forum_access']['troubleshooting'] = array(
327 '#type' => 'fieldset',
328 '#title' => t('Trouble-shooting node access'),
329 '#collapsible' => TRUE,
330 '#collapsed' => TRUE,
331 );
332 $form['forum_access']['troubleshooting'][] = array(
333 '#type' => 'item',
334 '#value' => '<div>'. t("In case of problems, follow these steps until you've got it worked out:") .'<ol style="margin-top: 0"><li>'.
335 t("Update to the 'recommended' !Forum_Access and !ACL releases for your version of Drupal.", $variables) .'</li><li>'.
336 (count($na_modules) ? t("Read %Module_interference above and update your other node access modules.", $variables) .'</li><li>' : '').
337 t("Check the release notes of the development snapshots for issues that might have been fixed in !Forum_Access-dev or !ACL-dev since the latest release.", $variables) .'</li><li>'.
338 t("Install the %devel_node_access module (!DNA, part of the !Devel module) and enable its !debug_mode: !DNA will show you all the grants that actually control your nodes in a footer block on each node's page.", $variables) .'</li><li>'.
339 t("Additional insight can be gained from !dna_summary and by enabling the second !DNA block.", $variables) .'</li><li>'.
340 t("Click !Rebuild_permissions on !Post_settings_link and check DNA for changes.", $variables) .'</li><li>'.
341 t("Check the issues queues of !Forum_Access_ and !ACL_ for existing reports and possible solutions.", $variables) .'</li><li>'.
342 t("If all of this hasn't helped, then pick ONE node that is misbehaving, look at it using an account that can see the node (and that should NOT have access if that's your problem!), create a new issue in the issues queue, describe the problem... <ul><li> what did you do? </li><li> what did you expect? </li><li> what happened instead? </li></ul> ... and <strong>attach a screenshot of all the DNA records</strong> for that one node. <br /> Be sure to indicate paths (URLs) for every page and module that you mention.") .'</li></ol></div>',
343 );
344 $form['forum_access']['troubleshooting'][] = array(
345 '#type' => 'item',
346 '#value' => '<div>'. t("Note: You should not keep the !Devel module enabled on a production site.", $variables) .'</div>',
347 );
348 }
349
350 if (!$is_container && isset($tid) && !node_access_needs_rebuild())
351 {
352 $count = db_result(db_query("SELECT COUNT(DISTINCT n.nid) FROM {node} n LEFT JOIN {term_node} tn ON tn.nid = n.nid WHERE tn.tid = %d", $tid));
353 $limit = 20; // from _node_access_rebuild_batch_operation()
354 $threshold = variable_get('forum_access_batch_threshold', $limit); // change the variable if you want
355 $form['forum_access']['update_limit'] = array(
356 '#type' => 'value',
357 '#value' => $limit,
358 );
359 $form['forum_access']['update_choice'] = array(
360 '#type' => 'radios',
361 '#title' => 'Update the permissions',
362 '#description' => t('<em>If</em> you make any node access changes, then each node in this forum needs to be updated. Hover over the radiobuttons for details.'),
363 '#options' => NULL,
364 0 => array(
365 '#type' => 'radio',
366 '#title' => t('for all %count nodes immediately', array('%count' => $count)),
367 '#attributes' => array('title' => t('This option is the fastest, but with many nodes it can still take considerable time and memory. If it fails, it will leave your !node_access table in an inconsistent state.', array('!node_access' => '{node_access}'))),
368 '#return_value' => 0,
369 '#default_value' => ($count <= $threshold ? 0 : 1),
370 '#parents' => array('forum_access', 'update_choice'),
371 ),
372 1 => array(
373 '#type' => 'radio',
374 '#title' => t('in batches of !limit now', array('!limit' => $limit)),
375 '#attributes' => array('title' => t('The batch option will always work reliably, but it takes longer to complete.')),
376 '#return_value' => 1,
377 '#default_value' => ($count <= $threshold ? 0 : 1),
378 '#parents' => array('forum_access', 'update_choice'),
379 ),
380 2 => array(
381 '#type' => 'radio',
382 '#title' => t('rebuild <strong>all</strong> permissions later'),
383 '#attributes' => array('title' => t("This option will only set a flag to remind you to rebuild all permissions later; this is useful if you want to make multiple changes to your node access settings quickly and delay the updating until you're done.")),
384 '#return_value' => 2,
385 '#default_value' => ($count <= $threshold ? 0 : 1),
386 '#parents' => array('forum_access', 'update_choice'),
387 ),
388 '#attributes' => array('class' => 'forum-access-flowed'),
389 );
390 }
391
392 // Move some stuff down so our block goes in a nice place.
393 $form['submit']['#weight'] = 10;
394 $form['delete']['#weight'] = 10;
395
396 $form['#validate'][] = '_forum_access_form_validate';
397 $form['#submit'][] = '_forum_access_form_submit';
398 }
399
400 function _forum_access_forum_form_disable_checkboxes($element) {
401 global $user;
402 static $permissions_by_rid = array();
403 if (empty($permissions_by_rid)) {
404 $permissions_by_rid[DRUPAL_AUTHENTICATED_RID] = '';
405 $result = db_query('SELECT r.rid, p.perm FROM {role} r LEFT JOIN {permission} p ON r.rid = p.rid ORDER BY r.rid');
406 while ($role = db_fetch_object($result)) {
407 $permissions_by_rid[$role->rid] = $role->perm .', '. ($role->rid != DRUPAL_ANONYMOUS_RID ? $permissions_by_rid[DRUPAL_AUTHENTICATED_RID] : '');
408 }
409 }
410 $tr = 't';
411 $moderator_rid = variable_get('forum_access_moderator_rid', NULL);
412
413 $element_children = element_children($element);
414 foreach ($element_children as $rid) {
415 if ($rid == $moderator_rid) {
416 $element[$rid]['#prefix'] = '<span title="'. t("This is the (temporary) @Forum_Moderator role; it has the '@administer_nodes' and '@administer_comments' permissions and is only used temporarily by @Forum_Access &mdash; do NOT give this role to any user!", array('@Forum_Moderator' => t('Forum Moderator'), '@administer_nodes' => $tr('administer nodes'), '@administer_comments' => $tr('administer comments'), '@Forum_Access' => 'Forum Access')) .'" class="forum-access-temporary-moderator">';
417 $element[$rid]['#suffix'] = "</span>";
418 $element[$rid]['#default_value'] = TRUE;
419 $element[$rid]['#disabled'] = TRUE;
420 }
421 elseif ($element['#parents'][1] == 'create') {
422 // Do nothing (Post is always mutable).
423 }
424 elseif ($element['#parents'][1] == 'view' && strstr($permissions_by_rid[$rid], 'administer forums,') !== FALSE) {
425 $element[$rid]['#title'] = '<em>'. $element[$rid]['#title'] .'</em>';
426 $element[$rid]['#prefix'] = '<span title="'. t("This role has the '@administer_forums' permission, and granting '@View' enables the role holders to change the settings on this page, including @Access_control!", array('@administer_forums' => $tr('administer forums'), '@View' => t('View'), '@Access_control' => t('Access control'))) .'">';
427 if (strstr($permissions_by_rid[$rid], 'administer nodes,') !== FALSE) {
428 $element[$rid]['#prefix'] = str_replace('">', ' '. t("Because the role also has the '@administer_nodes' permission, it has full access to all nodes either way.", array('@administer_nodes' => $tr('administer nodes'))) .'">', $element[$rid]['#prefix']);
429 }
430 $element[$rid]['#suffix'] = "</span>";
431 }
432 elseif (strstr($permissions_by_rid[$rid], 'administer nodes,') !== FALSE) {
433 $element[$rid]['#disabled'] = TRUE;
434 $element[$rid]['#default_value'] = TRUE;
435 $element[$rid]['#prefix'] = '<span title="'. ($rid != $moderator_rid
436 ? t("This role has the '@administer_nodes' permission and thus full access to all nodes.", array('@administer_nodes' => $tr('administer nodes')))
437 : t("This is the @Forum_Moderator role; it has the '@administer_nodes' and '@administer_comments' permissions and thus full access to all nodes and comments.", array('@Forum_Moderator' => t('Forum Moderator'), '@administer_nodes' => $tr('administer nodes'), '@administer_comments' => $tr('administer comments')))) .'">';
438 $element[$rid]['#suffix'] = "</span>";
439 }
440 }
441 return $element;
442 }
443
444 function _forum_access_forum_form_after_build_acl0($form, $form_state) {
445 if (isset($form['#post']['forum_access']['template']['taxonomy']))
446 {
447 // Get ACL's user_list for the template and replace it before ACL's after_build function gets its shot at it.
448 $template_tid = reset(array_values($form['#post']['forum_access']['template']['taxonomy']));
449 if ($acl_id = db_result(db_query("SELECT acl_id from {acl} WHERE module = 'forum_access' AND name = '%d'", $template_tid))) {
450 $f = acl_edit_form($acl_id, 'DUMMY');
451 $form['user_list']['#value'] = $f['user_list']['#default_value'];
452 }
453 }
454 return $form;
455 }
456
457 function _forum_access_forum_form_after_build_acl2($form, $form_state) {
458 if (!count(unserialize($form['user_list']['#default_value'])) && !count(unserialize($form['user_list']['#value']))) {
459 $form['#collapsed'] = TRUE;
460 }
461 if ($form['user_list']['#default_value'] != $form['user_list']['#value']) {
462 $form['note']['#value'] = preg_replace('/<div>/', '<div class="warning">', $form['note']['#value']);
463 }
464 return $form;
465 }
466
467 function _forum_access_forum_form_after_build($form, &$form_state) {
468 if (isset($form_state['clicked_button']['#name']) && $form_state['clicked_button']['#name'] == $form['template']['load_button']['#name'])
469 {
470 // Load a setting from a template:
471 $template_tid = reset(array_values($form['#post']['forum_access']['template']['taxonomy']));
472 $form_state['values']['forum_access']['template']['template_tid'] = $template_tid;
473 $form['template']['#collapsed'] = FALSE;
474
475 $settings = _forum_access_get_settings($template_tid);
476 foreach (array('view', 'create', 'update', 'delete') as $grant_type) {
477 if (empty($form[$grant_type])) {
478 continue;
479 }
480 foreach (element_children($form[$grant_type]) as $tid) {
481 $checked = array_search($tid, $settings[$grant_type]) !== FALSE;
482 $form[$grant_type][$tid]['#value'] = ($checked ? $tid : 0);
483 }
484 }
485 $form['interference']['advanced']['priority']['#value'] = $settings['priority'];
486 if ($settings['priority'] != 0) {
487 $form['interference']['advanced']['#collapsed'] = FALSE;
488 }
489 }
490 elseif (is_array(reset($form_state['values']['forum_access']['template']['taxonomy']))) {
491 $template_tid = reset(reset($form_state['values']['forum_access']['template']['taxonomy']));
492 }
493 if (isset($template_tid)) {
494 $form['template']['select_by_default']['#value'] = ($template_tid && $template_tid == variable_get('forum_access_default_template_tid', 0));
495 $form['template']['load_for_new']['#value'] = ($template_tid && $template_tid == variable_get('forum_access_new_template_tid', 0));
496 }
497 return $form;
498 }
499
500 function _forum_access_form_validate($form, &$form_state) {
501 global $user;
502
503 if ($user->uid == 1) {
504 return;
505 }
506 $access = $form_state['values']['forum_access']; // shortcut
507 foreach ($access['view'] as $rid => $checked) {
508 if ($checked && isset($user->roles[$rid])) {
509 return;
510 }
511 }
512 form_set_error('forum_access][view', t('You must assign %View access to a role that you hold.', array('%View' => 'View')));
513 }
514
515 function _forum_access_form_submit($form, &$form_state) {
516 $access = $form_state['values']['forum_access']; // shortcut
517
518 // Save template choice:
519 $template_tid = reset(array_values($access['template']['taxonomy']));
520 if ($access['template']['select_by_default']) {
521 variable_set('forum_access_default_template_tid', $template_tid);
522 }
523 elseif (variable_get('forum_access_default_template_tid', 0) == $template_tid) {
524 variable_del('forum_access_default_template_tid');
525 }
526 if ($access['template']['load_for_new']) {
527 variable_set('forum_access_new_template_tid', $template_tid);
528 }
529 elseif (variable_get('forum_access_new_template_tid', 0) == $template_tid) {
530 variable_del('forum_access_new_template_tid');
531 }
532 module_load_include('node.inc', 'forum_access');
533 $moderator_rid = _forum_access_get_moderator_rid(TRUE); // create the moderators role if it doesn't exist
534
535 // check for changes
536 $is_changed = $is_new = strpos($_GET['q'], 'admin/content/forum/add/') === 0;
537 $form_initial_values = $form; // avoid Coder warning
538 $form_initial_values = $form_initial_values['forum_access'];
539 foreach (array('view', 'create', 'update', 'delete') as $grant_type) {
540 if (isset($form_initial_values[$grant_type])) {
541 $defaults = $form_initial_values[$grant_type]['#default_value'];
542 $defaults = array_flip($defaults);
543 foreach ($access[$grant_type] as $tid => $checked) {
544 $is_changed = $is_changed || (empty($form_initial_values[$grant_type][$tid]['#disabled']) && !empty($checked) != isset($defaults[$tid]));
545 }
546 }
547 }
548 if (!$is_changed && $access['acl']['user_list'] == $form_initial_values['acl']['user_list']['#default_value'] && $access['interference']['advanced']['priority'] == $form_initial_values['interference']['advanced']['priority']['#default_value']) {
549 drupal_set_message(t('The content access permissions are unchanged.'));
550 return;
551 }
552
553 db_query("DELETE FROM {forum_access} WHERE tid = %d", $form_state['values']['tid']);
554
555 $fa_priority = isset($access['interference']['advanced']['priority']) ? $access['interference']['advanced']['priority'] : 0;
556 if (array_key_exists('acl', $access)) {
557 $moderators = unserialize($access['acl']['user_list']);
558 acl_save_form($access['acl'], $fa_priority);
559 }
560 foreach ($access['view'] as $rid => $checked) {
561 if ($rid == $moderator_rid) {
562 continue;
563 }
564 $grants[] = array(
565 'realm' => 'forum_access',
566 'gid' => $rid,
567 'grant_view' => (bool) $checked,
568 'grant_update' => !empty($access['update'][$rid]),
569 'grant_delete' => !empty($access['delete'][$rid]),
570 'priority' => $fa_priority,
571 );
572 db_query("INSERT INTO {forum_access} (tid, rid, grant_view, grant_update, grant_delete, grant_create, priority) VALUES (%d, %d, %d, %d, %d, %d, %d)", $form_state['values']['tid'], $rid, (bool) $checked, !empty($access['update'][$rid]), !empty($access['delete'][$rid]), !empty($access['create'][$rid]), $fa_priority);
573 }
574 $tid = $form_state['values']['tid'];
575 $link = l(t('edit'), 'admin/content/forum/edit/forum/'. $tid);
576 watchdog('access', 'Changed grants for %forum forum.', array('%forum' => $form_state['values']['name']), WATCHDOG_NOTICE, $link);
577
578 if (!$is_new && $form_state['values']['form_id'] != 'forum_form_container') {
579 if (!isset($access['update_choice']) || $access['update_choice'] == 2) {
580 node_access_needs_rebuild(TRUE);
581 }
582 elseif ($access['update_choice'] == 0) {
583 // update immediately (but use the batch functions anyway
584 $save_redirect = $form_state['redirect'];
585 $form_state['redirect'] = $_GET['q'];
586 $context = array();
587 $pending_error_messages = drupal_get_messages('error', FALSE);
588 $our_error_message_index = (isset($pending_error_messages['error']) ? count($pending_error_messages['error']) : 0);
589 _forum_access_update_batch_finished(FALSE, array(), array()); // add our error message (in case we die underway)
590 _forum_access_update_batch_operation($form_state['values']['tid'], 999999, 1, $context);
591 $pending_error_messages = drupal_get_messages('error', TRUE); // still alive, get and clear all 'error' messages
592 unset($pending_error_messages['error'][$our_error_message_index]); // remove our error message
593 foreach ($pending_error_messages['error'] as $message) { // replay any others
594 drupal_set_message($message, 'error');
595 }
596 _forum_access_update_batch_finished(TRUE, array(), array());
597 $form_state['redirect'] = $save_redirect;
598 }
599 else {
600 // mass update in batch mode, modeled after node.module
601 $limit = $access['update_limit'];
602 $count = db_result(db_query("SELECT COUNT(DISTINCT n.nid) FROM {node} n LEFT JOIN {term_node} tn ON tn.nid = n.nid WHERE tn.tid = %d", $form_state['values']['tid']));
603 $batch = array(
604 'title' => t('Updating content access permissions'),
605 'file' => drupal_get_path('module', 'forum_access') .'/forum_access.admin.inc',
606 'operations' => array(
607 array('_forum_access_update_batch_operation', array($form_state['values']['tid'], $limit, $count)),
608 ),
609 'finished' => '_forum_access_update_batch_finished'
610 );
611 batch_set($batch);
612 }
613 }
614 }
615
616 /**
617 * Batch operation for forum_access_form_submit().
618 *
619 * This is a mutlistep operation : we go through all nodes by packs of 20.
620 * The batch processing engine interrupts processing and sends progress
621 * feedback after 1 second execution time.
622 */
623 function _forum_access_update_batch_operation($tid, $limit, $count, &$context) {
624 if (empty($context['sandbox'])) {
625 // Initiate multistep processing.
626 $context['sandbox']['progress'] = 0;
627 $context['sandbox']['current_node'] = 0;
628 $context['sandbox']['max'] = $count;
629 }
630
631 // Process the next 20 nodes.
632 $result = db_query_range("SELECT n.nid FROM {node} n LEFT JOIN {term_node} tn ON tn.nid = n.nid WHERE n.nid > %d AND tn.tid = %d ORDER BY n.nid ASC", $context['sandbox']['current_node'], $tid, $context['sandbox']['current_node'], 0, $limit);
633 while ($row = db_fetch_array($result)) {
634 $loaded_node = node_load($row['nid'], NULL, TRUE);
635 // To preserve database integrity, only aquire grants if the node
636 // loads successfully.
637 if (!empty($loaded_node)) {
638 node_access_acquire_grants($loaded_node);
639 }
640 $context['sandbox']['progress']++;
641 $context['sandbox']['current_node'] = $loaded_node->nid;
642 }
643
644 // Multistep processing : report progress.
645 if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
646 $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
647 }
648 }
649
650 /**
651 * Post-processing for forum_access_form_submit().
652 */
653 function _forum_access_update_batch_finished($success, $results, $operations) {
654 if ($success) {
655 drupal_set_message(t('The content access permissions have been updated.'));
656 cache_clear_all();
657 }
658 else {
659 drupal_set_message(t('The content access permissions have not been properly updated.'), 'error');
660 }
661 }
662
663 /**
664 * Add our settings to the forum administration settings page.
665 */
666 function _forum_access_forum_admin_settings_form(&$form, &$form_state) {
667 $variables = array(
668 '!Forum_Access' => 'Forum Access',
669 '%View' => 'View',
670 '%Post' => 'Post',
671 '%post_comments' => 'post comments',
672 );
673 $form['forum_access'] = array(
674 '#type' => 'fieldset',
675 '#title' => 'Forum Access',
676 '#attributes' => array('id' => 'edit-forum-admin-settings-forum-access'),
677 );
678 $form['forum_access']['note'] = array(
679 '#type' => 'item',
680 '#value' => t('Note: All other !Forum_Access controls are on the administration pages of the individual forums.', $variables),
681 );
682 $form['forum_access']['forum_access_D5_legacy_mode'] = array(
683 '#type' => 'checkbox',
684 '#title' => t('Drupal 5 legacy mode', $variables),
685 '#default_value' => variable_get('forum_access_D5_legacy_mode', FALSE),
686 '#description' => t('In Drupal 5, comment posting was not restricted by !Forum_Access; users with %View access (and the %post_comments permission) were always allowed to post forum comments. Starting with Drupal 6, posting comments is now restricted to users with %Post access. Turn this option on to revert to the old behavior. The default is OFF.', $variables),
687 );
688 $buttons = $form['buttons'];
689 unset($form['buttons']);
690 $form['buttons'] = $buttons;
691 }
692
693 /**
694 * Helper function to retrieve the settings for a forum.
695 */
696 function _forum_access_get_settings($tid = NULL) {
697 $return = array('view' => array(), 'create' => array(), 'update' => array(), 'delete' => array(), 'priority' => 0);
698 if (!isset($tid)) {
699 // Default to all users can read; all logged in users can post.
700 $return['view'] = array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID);
701 $return['create'] = array(DRUPAL_AUTHENTICATED_RID);
702 }
703 else {
704 $result = db_query("SELECT * FROM {forum_access} where tid=%d", $tid);
705 while ($access = db_fetch_object($result)) {
706 $row_received = TRUE;
707 if ($access->grant_view) {
708 $return['view'][] = $access->rid;
709 }
710 if ($access->grant_update) {
711 $return['update'][] = $access->rid;
712 }
713 if ($access->grant_delete) {
714 $return['delete'][] = $access->rid;
715 }
716 if ($access->grant_create) {
717 $return['create'][] = $access->rid;
718 }
719 if ($access->rid == DRUPAL_AUTHENTICATED_RID) { // this is our reference
720 $return['priority'] = $access->priority;
721 }
722 }
723 if (empty($row_received)) {
724 // Return default settings if no records found in database.
725 $return = _forum_access_get_settings();
726 }
727 }
728 return $return;
729 }
730
731 /**
732 * Remove unusable 'edit' links from overview form.
733 */
734 function _forum_access_forum_overview(&$form, &$form_state) {
735 global $user;
736 if ($user->uid == 1) {
737 return;
738 }
739 foreach ($form as $key => $value) {
740 if (preg_match('/^tid:(.*):0$/', $key, $matches)) {
741 if (!forum_access_access($matches[1], 'view')) {
742 unset($form[$key]['edit']['#value']);
743 }
744 }
745 }
746 }
747
748 /**
749 * We must know when a role is deleted.
750 */
751 function _forum_access_user_admin_role_form(&$form, &$form_state) {
752 $form['#submit'][] = '_forum_access_user_admin_role_submit';
753 }
754
755 /**
756 * If a role is deleted, we remove the grants it provided.
757 * Also, we complain if the Forum Moderator role is deleted.
758 */
759 function _forum_access_user_admin_role_submit($form, &$form_state) {
760 if ($form_state['values']['op'] == $form_state['values']['delete']) {
761 $rid = $form_state['values']['rid'];
762 db_query("DELETE FROM {forum_access} WHERE rid = %d", $rid);
763 db_query("DELETE FROM {node_access} WHERE gid = %d AND realm = 'forum_access'", $rid);
764 if ($rid === variable_get('forum_access_moderator_rid', NULL)) {
765 drupal_set_message(t('The role you have just deleted is required by !Forum_Access; it will be recreated automatically.', array('!Forum_Access' => 'Forum Access')), 'error');
766 }
767 }
768 }
769
770 /**
771 * Add warnings on Content Access admin forms where CA wants
772 * to control the same content types as we do.
773 */
774 function _forum_access_content_access_admin_form() {
775 $tr = 't';
776 $variables = array(
777 '!Content_Access' => 'Content Access',
778 '!Forum_Access' => 'Forum Access',
779 '!Forum_Access_link' => l('Forum Access', 'admin/content/forum'),
780 '%anonymous_user' => $tr('anonymous user'),
781 '%authenticated_user' => $tr('authenticated user'),
782 '%Advanced' => $tr('Advanced'),
783 );
784 if (arg(3) == 'forum') {
785 drupal_set_message(t('Note: In Drupal, access can only be granted, not taken away. Whatever access you grant here will not be reflected in the !Forum_Access_link settings, but !Forum_Access can only allow <i>more</i> access, not less.', $variables)
786 .'<br /><span class="error">'. t('Specifically, any rights granted to the %anonymous_user and/or the %authenticated_user will <b>override</b> the settings of !Forum_Access!', $variables) .'</span>'
787 .'<br />'. t('To avoid conflicts with !Forum_Access settings, you may want to lower the priority of !Content_Access (under %Advanced below) below the priority of !Forum_Access for the content types that you want to be controlled by !Forum_Access.', $variables), 'warning');
788 }
789 else {
790 $vid = variable_get('forum_nav_vocabulary', '');
791 $vocabulary = taxonomy_vocabulary_load($vid);
792 if (isset($vocabulary->nodes[arg(3)]))
793 {
794 drupal_set_message(t('Note: Nodes of this content type can be put inside forums, where access to them will also be controlled by !Forum_Access.<br />In Drupal, access can only be granted, not taken away. Whatever access you grant here will not be reflected on the !Forum_Access_link settings, and vice versa, but any node access module can only allow <i>more</i> access, not less.', $variables), 'warning');
795 }
796 }
797 }
798
799 /*
800 * Create the Forum Moderator role.
801 */
802 function _forum_access_create_moderator_rid($verbose = FALSE) {
803 $tr = 't';
804 $variables = array('!Forum_Access' => 'Forum Access', '%administer_comments' => $tr('administer comments'), '%administer_nodes' => $tr('administer nodes'));
805 $role_name = t('Forum Moderator');
806 $role = new stdClass();
807 $role->name = $role_name;
808 for ($i = 2; $i <= 12; ++$i) {
809 $variables['%role'] = $role->name;
810 if (!db_result(db_query("SELECT COUNT(rid) FROM {role} WHERE name = '%s'", $role->name)) &&
811 drupal_write_record('role', $role)) {
812 $rid = $role->rid;
813 variable_set('forum_access_moderator_rid', $rid);
814 $permission = new stdClass();
815 $permission->rid = $rid;
816 $permission->perm = 'administer comments, administer nodes';
817 drupal_write_record('permission', $permission);
818 $msg = t('!Forum_Access has created a new role named %role and given it the %administer_nodes and %administer_comments permissions. This role is used internally by !Forum_Access. You can change the name of the role as you like, but you must keep it unmodified otherwise.', $variables);
819 if ($verbose) {
820 drupal_set_message($msg, 'warning');
821 }
822 watchdog('user', $msg, NULL, WATCHDOG_NOTICE);
823 return $rid;
824 }
825 else {
826 $msg = t('!Forum_Access cannot create the %role role!', $variables);
827 watchdog('user', $msg, NULL, WATCHDOG_WARNING);
828 drupal_set_message($msg .' '. t('Is it already in use?'), 'error');
829 $role->name = $role_name ." $i";
830 }
831 }
832 $msg = t('!Forum_Access has given up and will not work correctly! Rename one of the roles listed above, so that !Forum_Access can use its name.', $variables);
833 drupal_set_message($msg, 'error');
834 watchdog('user', $msg, NULL, WATCHDOG_CRITICAL);
835 }
836

  ViewVC Help
Powered by ViewVC 1.1.2