/[drupal]/contributions/modules/taxonomy_access/taxonomy_access.module
ViewVC logotype

Contents of /contributions/modules/taxonomy_access/taxonomy_access.module

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


Revision 1.102 - (show annotations) (download) (as text)
Sat Nov 18 17:14:51 2006 UTC (3 years ago) by keve
Branch: MAIN
Branch point for: DRUPAL-5
Changes since 1.101: +82 -1 lines
File MIME type: text/x-php
#92355 by AjK: Node_form: preserves terms deleted by taxonomy_node_delete() that the user shouldn't have access to delete.
1 <?php
2 // $Id: taxonomy_access.module,v 1.101 2006/11/12 10:06:15 keve Exp $
3 // Based on original taxonomy_access.module made by pyromanfo
4
5 /**
6 * @file
7 * Allows administrators to specify how each category (in the taxonomy) can be used by various roles.
8 */
9
10
11 /**
12 * Implementation of hook_help
13 */
14 function taxonomy_access_help($section) {
15 global $tac_user_roles;
16 switch ($section) {
17 // Creates the header content for the taxonomy_access settings page dependent upon
18 // whether the node is enabled or disabled.
19 // Note: the form that appears on this page is not generated by this fucntion.
20 case 'admin/settings/taxonomy_access':
21 $message = 'Some new options coming soon...';
22 return $message;
23
24 case 'admin/help#taxonomy_access':
25 $message = '<p>'.t('The Taxonomy Access Control module allows users to specify how each category can be used by various roles.').'</p>';
26 $message .= '<p>'.t('Permissions can be set differently to each USER ROLES. When a USER is assigned to TWO OR MORE USER ROLES, then he receives permissions from ALL OF HIS USER ROLES.').'</p>';
27 $message .= '<p>'.t('On the category permissions page for each role, each category displays a list of the terms within it, each with five types of permission: <em>View, Update, Delete, Create</em> and <em>List</em>:').'</p>';
28 $message .= '<ul>';
29 $message .= '<li>'.t('<strong>VIEW</strong> enables the user to access content (nodes) with given term.').'</li>';
30 $message .= '<li>'.t('<strong>UPDATE, DELETE</strong> enables the user to Update/Delete <u>ALL</u> nodes with the given term. <br><em>(These two permissions are <u>administrator permissions</u>, that should be given ONLY to e.g. content administrators.)</em>').'</li>';
31 $message .= '<li>'.t('<strong>CREATE</strong> enables the user to set that term when adding a new node or when editing a node.').'</li>';
32 $message .= '<li>'.t('<strong>LIST</strong> enables the user to view the name of the given term below the title of a node or in category lists. It also controls whether a user can access the taxonomy page for the given term. (e.g. "taxonomy/term/*")').'</li>';
33 $message .= '</ul>';
34 $message .= '<p>'.t('VIEW, UPDATE, and DELETE control the node access system. LIST and CREATE control if a user can view and select a given term. (Note: In previous versions of Taxonomy Access Control, there was no LIST permission; its functionality was controlled by the VIEW permission.)').'</p>';
35 $message .= '<p>'.t('<strong>VIEW, UPDATE and DELETE have three options for each term: <u>A</u>llow, <u>I</u>gnore, and <u>D</u>eny.</strong> Indicate which rights each role should have for each term.').'</p>';
36 $message .= '<p>'.t('<strong>CREATE and LIST have only two options for each term: YES (selected) or NO (deselected).</strong> Indicate what each role should be allowed to do with each term.').'</p>';
37 $message .= '<p>'.t('<strong>IMPORTANT NOTE:</strong><br><u>The DENY directives are processed after the ALLOW directives. (DENY overrides ALLOW.)</u> So, if a multicategory node is in Categories "A" and "B" and a user has ALLOW permissions for VIEW in Category "A" and DENY permissions for VIEW in Category "B", then the user will NOT be permitted to VIEW the node. (DENY overrides ALLOW.)<br><u>Access is denied by default.</u> So, if a multicategory node is in Categories "C" and "D" and a user has IGNORE permissions for VIEW in both Category "C" and "D", then the user will NOT be permitted to VIEW the node.<br>(If you are familiar with Apache mod_access, this permission system works similar to directive: <em>ORDER ALLOW, DENY</em>)').'</p>';
38 $message .= '<p>'.t('<strong>Allow/Ignore/Deny All</strong> or <strong>Select/Deselect All:</strong><br>Beside each vocabulary title there are dropdowns containing the options that can be set for individual terms. Selecting one of these options using the dropdown effectively <u>selects that option for ALL of the individual terms inside that vocabulary when the options are saved.</u><br>Selecting "--" does not make any automatic changes to the permission of the terms in that vocabulary; only manual changes that you make will be saved.<br>NOTE: This does <u>not</u> change the "Default" option (described below).').'</p>';
39 $message .= '<p>'.t('<strong>Default:</strong><br>This option, just underneath the vocabulary title, <u>sets the permission that will automatically be given</u> to the role, <u>for any new terms</u> that are added within the vocabulary. This includes terms that are added via free tagging.').'</p>';
40 $message .= '<p>'.t('<strong>GOOD TO KNOW:</strong><br><strong>Input formats:</strong> <u>Node editing/deleting is blocked</u>, even when user has <em>UPDATE/DELETE</em> permission to the node, <u>when user is not allowed to use a filter format</u> that the node was saved at.').'</p>';
41 $message .= '<p>&nbsp;</p>';
42 return $message;
43
44 default:
45 if (strpos($section,'admin/user/taxonomy_access') === 0) {
46 $rid = arg(3);
47 if (isset($tac_user_roles[$rid]) && $tac_user_roles[$rid]) {
48 $output = t('<p><strong>Vocabulary Settings:</strong> Each vocabulary displays a list of the terms within it, each with five types of permission: <em>View, Update, Delete, Create</em> and <em>List</em>.</p><p>For a detailed description of these permissions and how to use them, see <a href="@taxonomy_access_help">Taxonomy Access Control help</a>. If you are new to Taxonomy Access Control, it is very important that you read the help page.</p>', array('@taxonomy_access_help' => url('admin/help/taxonomy_access')));
49 return $output;
50 }
51 else {
52 return '<p>'.t('In this area you will define the permissions that each <a href="@role">user role</a> has for each category. Each category can have <em>View, Update, Delete, Create</em> and <em>List</em> permissions set for each user role.', array('@role' => url('admin/user/roles'))).'</p>';
53 }
54 }
55 }
56 }
57
58 /**
59 * Implementation of hook_enable().
60 *
61 * Need to housekeep term_access databases for new/deleted terms/users to ensure they are up-to-date.
62 */
63 function taxonomy_access_enable() {
64 _taxonomy_access_update_db();
65 }
66
67 /**
68 * Implementation of hook_disable().
69 *
70 * Need to force a rebuild of the node access table when TAC is disabled
71 * to ensure that its entries are removed from the table.
72 */
73 function taxonomy_access_disable() {
74 taxonomy_access_disabling(TRUE);
75 node_access_rebuild();
76
77 }
78
79 /**
80 * Simple function to make sure we don't respond with grants when disabling
81 * ourselves.
82 */
83 function taxonomy_access_disabling($set = NULL) {
84 static $disabling = false;
85 if ($set !== NULL) {
86 $disabling = $set;
87 }
88 return $disabling;
89 }
90
91 /**
92 * Implementation of hook_node_grants()
93 * Gives access to taxonomies based on the taxonomy_access table
94 */
95 function taxonomy_access_node_grants($user, $op) {
96 return array('term_access' => array_keys(is_array($user->roles) ? $user->roles : array(1 => 'anonymous user')));
97 }
98
99 /**
100 * Implementation of hook_node_access_records().
101 */
102 function taxonomy_access_node_access_records($node) {
103 if (taxonomy_access_disabling()) {
104 return;
105 }
106
107 $grants = array();
108
109 $where = "WHERE n.nid = ".$node->nid;
110 $result = db_query("SELECT n.nid, ta.rid, BIT_OR(ta.grant_view) AS grant_view, BIT_OR(ta.grant_update) AS grant_update, BIT_OR(ta.grant_delete) AS grant_delete FROM {term_node} n INNER JOIN {term_access} ta ON n.tid = ta.tid $where GROUP BY n.nid, ta.rid");
111
112 while($row = db_fetch_object($result)) {
113 if ($row) {
114 $grant_view = ($row->grant_view == 1) ? 1 : 0;
115 $grant_update = ($row->grant_update == 1) ? 1 : 0;
116 $grant_delete = ($row->grant_delete == 1) ? 1 : 0;
117
118 $grants[] = array(
119 'realm' => 'term_access',
120 'gid' => $row->rid,
121 'grant_view' => $grant_view,
122 'grant_update' => $grant_update,
123 'grant_delete' => $grant_delete,
124 'priority' => 0,
125 );
126 }
127 }
128
129 // Determine if node doesn't belong to a category
130 $where = "AND n.nid = ".$node->nid;
131 $result = db_query("SELECT n.nid, ta.* FROM {node} n LEFT JOIN {term_node} t ON t.nid=n.nid LEFT JOIN {term_access} ta ON ta.tid = 0 WHERE t.nid IS NULL $where");
132 while($row = db_fetch_object($result)) {
133 if ($row) {
134 $grant_view = ($row->grant_view == 1) ? 1 : 0;
135 $grant_update = ($row->grant_update == 1) ? 1 : 0;
136 $grant_delete = ($row->grant_delete == 1) ? 1 : 0;
137
138 $grants[] = array(
139 'realm' => 'term_access',
140 'gid' => $row->rid,
141 'grant_view' => $grant_view,
142 'grant_update' => $grant_update,
143 'grant_delete' => $grant_delete,
144 'priority' => 0,
145 );
146 }
147 }
148
149 return $grants;
150 }
151
152 /**
153 * Implementation of hook_menu
154 */
155 function taxonomy_access_menu($may_cache) {
156 $items = array();
157
158 // Only include administrative callbacks if we are viewing an admin page.
159 if (arg(0) == 'admin') {
160 include_once(drupal_get_path('module', 'taxonomy_access') .'/taxonomy_access_admin.inc');
161 }
162
163 if ($may_cache) {
164 $items[] = array(
165 'path' => 'admin/settings/taxonomy_access',
166 'title' => t('Taxonomy Access settings'),
167 // 'description' => t('Configure Taxonomy Access Control'),
168 'callback' => 'drupal_get_form',
169 'callback arguments' => array('_taxonomy_access_admin_settings'),
170 'access' => user_access('administer site configuration'),
171 );
172 $items[] = array(
173 'path' => 'admin/user/taxonomy_access',
174 'title' => t('Taxonyom Access permissions'),
175 'description' => t('Sophisticated access control for content items based on category'),
176 'callback' => '_taxonomy_access_permissions_page',
177 'access' => user_access('administer access control'),
178 );
179 }
180
181 return $items;
182 }
183
184 /**
185 * Implementation of hook_form_alter()
186 */
187 function taxonomy_access_form_alter($form_id, &$form) {
188
189 if ($form['#id'] == 'node-form' && is_numeric($form['nid']['#value'])) {
190 $form['tac_protected_terms'] = array(
191 '#type' => 'value',
192 '#value' => taxonomy_access_preserve_terms($form['nid']['#value'])
193 );
194 }
195 }
196
197 /**
198 * Updates permissions for a role for a term
199 * @param $tid
200 * The term to add the permission for.
201 * @param $role
202 * The role to add the permission to.
203 * Can be the name or the role id or blank for all term permissions.
204 * @param $grants
205 * A hash of the grants in the form of $grants['perm'] = boolean
206 * A value of 1 will grant the permission for this user and term.
207 **/
208 function taxonomy_access_grant_update($tid, $role = null, $grants = null) {
209 if (!isset($tid)) {
210 return FALSE;
211 }
212 if (isset($role) && !is_numeric($role)) {
213 $role = db_result(db_query("SELECT rid FROM {role} WHERE name='$role'"));
214 }
215
216 $ta_sql = "INSERT INTO {term_access} (tid";
217 $ta_sql_values = " VALUES ($tid";
218 if (isset($role)) {
219 $ta_sql .= ",rid";
220 $ta_sql_values .= ",$role";
221 }
222 $sql = "";
223 if (isset($grants)) {
224 foreach ($grants as $perm => $value) {
225 $sql .= ",grant_$perm";
226 $ta_sql_values .= is_array($value) ? ",".$value[0] : ",$value";
227 }
228 $sql .= ")";
229 $ta_sql_values .= ")";
230 }
231 else {
232 $sql .= ")";
233 $ta_sql_values .= ")";
234 }
235 $ta_sql .= $sql . $ta_sql_values;
236
237 db_query("DELETE FROM {term_access} WHERE tid=%d AND rid=%d", $tid, (isset($role) ? $role : 0));
238 db_query($ta_sql); // insert into term_access
239 }
240
241 /**
242 * Updates default permissions for a role for a vocabulary
243 * @param $vid
244 * The vocab to add the permission for.
245 * @param $role
246 * The role to add the permission to.
247 * Can be the name or the role id or blank for all term permissions.
248 * @param $grants
249 * A hash of the grants in the form of $grants['perm'] = boolean
250 * A value of 1 will grant the permission for this user and term.
251 **/
252 function taxonomy_access_defaults_update($vid, $role = null, $grants = null) {
253 if (!isset($vid)) {
254 return FALSE;
255 }
256 if (isset($role) && !is_numeric($role)) {
257 $role = db_result(db_query("SELECT rid FROM {role} WHERE name='$role'"));
258 }
259
260 $ta_sql = "INSERT INTO {term_access_defaults} (vid";
261 $ta_sql_values = " VALUES ($vid";
262 if (isset($role)) {
263 $ta_sql .= ",rid";
264 $ta_sql_values .= ",$role";
265 }
266 $sql = "";
267 if (isset($grants)) {
268 foreach ($grants as $perm => $value) {
269 $sql .= ",grant_$perm";
270 $ta_sql_values .= ",$value";
271 }
272 $sql .= ")";
273 $ta_sql_values .= ")";
274 }
275 else {
276 $sql .= ")";
277 $ta_sql_values .= ")";
278 }
279 $ta_sql .= $sql . $ta_sql_values;
280
281 db_query("DELETE FROM {term_access_defaults} WHERE vid=%d AND rid=%d", $vid, (isset($role) ? $role : 0));
282 db_query($ta_sql); // insert into term_access_defaults
283 }
284 /**
285 * Updates permissions for a role for all the terms in a vocabulary
286 * @param $vid
287 * The vocabulary to search for terms to add the permission for.
288 * @param $role
289 * The role to add the permission to.
290 * Can be the name or the role id or blank for all term permissions.
291 * @param $grants
292 * A hash of the grants in the form of $grants['perm'] = boolean
293 * A value of 1 will grant the permission for this user and term.
294 **/
295 function taxonomy_access_grant_vocab_update($vid, $rid = null, $edit = null) {
296 $tree = taxonomy_get_tree($vid);
297 $grant_types = array('view', 'update', 'delete', 'create', 'list');
298 $vgrants = $edit[$vid]['vocab'];
299 $grants = array();
300 foreach ($tree as $term) {
301 foreach ($grant_types as $grant) {
302 if (in_array($vgrants[$grant], array( 0, 1, 2))) {
303 $grants[$grant] = $vgrants[$grant];
304 }
305 else {
306 $grants[$grant] = $edit[$term->vid]['term'][$term->tid][$grant];
307 }
308 }
309 taxonomy_access_grant_update($term->tid,$rid,$grants);
310 }
311 }
312
313 /**
314 * Gets permissions for a given role
315 * @param $role
316 * The role to retrieve the permissions for.
317 * Can be the name or the role id or blank for all term permissions.
318 * @return
319 * A two dimensional hash of the form $grants[tid][grant] where
320 * tid is the term id and
321 * grant is the permission (i.e. 'view','delete',ect.)
322 * this entry in the hash is true if permission is granted, false otherwise
323 **/
324 function taxonomy_access_get_grants($role) {
325 if (!isset($role)) {
326 return false;
327 }
328 if (isset($role) && !is_numeric($role)) {
329 $role = db_result(db_query("SELECT rid FROM {role} WHERE name='$role'"));
330 }
331 $result = db_query("SELECT * FROM {term_access} WHERE rid='$role'");
332 $grants = array();
333 while ($grant = db_fetch_array($result)) {
334 $tid = $grant['tid'];
335 foreach ($grant as $key => $grant_val) {
336 if (strpos($key,'grant_') !== FALSE) {
337 $grant_name = '';
338 $grant_name = str_replace('grant_','',$key);
339 if (!isset($grants[$tid][$grant_name]) || !($grants[$tid][$grant_name])) {
340 // If there's conflicting DB rules, take the most lenient
341 $grants[$tid][$grant_name] = $grant_val;
342 }
343 }
344 }
345 }
346 return $grants;
347 }
348 /**
349 * Gets default permissions for a given role
350 * @param $role
351 * The role to retrieve the permissions for.
352 * Can be the name or the role id or blank for all term permissions.
353 * @return
354 * A two dimensional hash of the form $grants[vid][grant] where
355 * vid is the vocab id and
356 * grant is the permission (i.e. 'view','delete',ect.)
357 * this entry in the hash is true if permission is granted, false otherwise
358 **/
359 function taxonomy_access_get_default_grants($role) {
360 if (!isset($role)) {
361 return false;
362 }
363 if (isset($role) && !is_numeric($role)) {
364 $role = db_result(db_query("SELECT rid FROM {role} WHERE name='$role'"));
365 }
366 $result = db_query("SELECT * FROM {term_access_defaults} WHERE rid='$role'");
367 $grants = array();
368 while ($grant = db_fetch_array($result)) {
369 $vid = $grant['vid'];
370 foreach ($grant as $key => $grant_val) {
371 if (strpos($key,'grant_') !== FALSE) {
372 $grant_name = '';
373 $grant_name = str_replace('grant_','',$key);
374 if (!isset($grants[$vid][$grant_name]) || !($grants[$vid][$grant_name])) {
375 // If there's conflicting DB rules, take the most lenient
376 $grants[$vid][$grant_name] = $grant_val;
377 }
378 }
379 }
380 }
381 return $grants;
382 }
383
384 /**
385 * Implementation of hook_nodeapi().
386 */
387 function taxonomy_access_nodeapi(&$node, $op, $arg = 0) {
388 switch ($op) {
389 case 'submit':
390 // When TAC grants 'update' access to edit node,
391 // Changing $node->uid back to original creator (changed by node_submit)
392 if (($node->nid) && !user_access('administer nodes') && (node_access('update', $node))) {
393 // Populate the "authored by" field.
394 $old_node = node_load($node->nid);
395 if ($account = user_load(array('name' => $old_node->name))) {
396 $node->uid = $account->uid;
397 }
398 else {
399 $node->uid = 0;
400 }
401 }
402 break;
403
404 case 'update':
405 // restore terms that the user shouldn't have access to delete
406 taxonomy_access_restore_terms($node->nid, $node->tac_protected_terms);
407 break;
408 }
409 }
410
411
412 /**
413 * hook_taxonomy is called when changes are made to the taxonomy structure
414 **/
415 function taxonomy_access_taxonomy($op, $type, $edit = NULL) {
416 if ($type == 'term') {
417 switch($op) {
418 case 'update': // don't do anything, nothing on our end has changed
419 break;
420
421 case 'insert': // add new default entries for the new category, don't have to touch node_access since no posts are in there yet
422 foreach (user_roles() as $rid => $role) {
423 $grants = db_fetch_object(db_query("SELECT * FROM {term_access_defaults} WHERE vid='%d' AND rid='%d'",$edit['vid'], $rid));
424 db_query("DELETE FROM {term_access} WHERE tid='%d' AND rid='%d'",$edit['tid'],$rid);
425 db_query('INSERT INTO {term_access} VALUES (\'%d\', \'%d\', %d, %d, %d, %d, %d)', $edit['tid'], $rid, $grants->grant_view,$grants->grant_update,$grants->grant_delete,$grants->grant_create,$grants->grant_list);
426 }
427 break;
428
429 case 'delete': // delete everything from term_access and node_access
430 db_query("DELETE FROM {term_access} WHERE tid='%d'",$edit['tid']);
431 node_access_rebuild();
432 break;
433 }
434 }
435 return;
436 }
437
438 /**
439 * _user hook called when a user event occurs to check for new roles. It would make sense to have a _role hook
440 * instead. However, that hook doesn't exist so we rely on the _user hook to determine if new roles have been added.
441 **/
442 function taxonomy_access_user($op, &$edit, &$user, $category = NULL) {
443 if ($op == 'update' || $op == 'insert') {
444 // Get list of existing roles
445 $result = db_query('SELECT rid FROM {role}');
446 while ($rids = db_fetch_array($result)) {
447 $current_rids[] = $rids['rid'];
448 }
449 if (!in_array(0, $current_rids)) {
450 $current_rids[] = 0;
451 }
452
453 // Get list of roles known to exist from term_access
454 $known_rids = array();
455 $result = db_query('SELECT DISTINCT rid FROM {term_access}');
456 while($rids = db_fetch_array($result)) {
457 $known_rids[] = $rids['rid'];
458 }
459 if (!in_array(0, $known_rids)) {
460 $known_rids[] = 0;
461 }
462
463 if (array_diff($current_rids, $known_rids)) {
464 _taxonomy_access_update_db($current_rids, $known_rids);
465 }
466 }
467 }
468
469 /*
470 * Housekeeping for the term_access and term_access_defaults tables
471 *
472 * Called when the TAC module is enabled to reflect the changes since it was disabled:
473 * 1: Check for new/deleted taxonomy terms and make approprate entries into term_access table (according to term_access_defaults)
474 * 2: Check for new/deleted user roles and make approprate entries into term_access table
475 * 3: Check for new/deleted taxonomy vocabularies and user roles to update term_access_defaults table
476 * 4: Force to rebuild the node_access table based on the new changes in the Taxonomy Access system
477 */
478 function _taxonomy_access_update_db($current_rids = NULL, $old_rids = NULL) {
479 // BEGIN: term_access table housekeeping
480 // Update the term_access table to reflect any changes that may have occured since module was disabled.
481 $tids = array();
482 $rids = array();
483
484 // Create list of all term and role ids
485 $query = db_query('SELECT tid FROM {term_data}');
486 while ($result = db_fetch_array($query)) {
487 $current_tids[] = $result['tid'];
488 }
489 $current_tids[] = 0;
490
491 if (!$current_rids) {
492 $query = db_query('SELECT rid FROM {role}');
493 while ($result = db_fetch_array($query)) {
494 $current_rids[] = $result['rid'];
495 }
496 // $current_rids[] = 0; no default non-roled access
497 }
498 $current_vids = array();
499 $query = db_query('SELECT vid FROM {vocabulary}');
500 while ($result = db_fetch_array($query)) {
501 $current_vids[] = $result['vid'];
502 }
503
504 // Get old list of term and role ids from when term_access was disabled
505 $old_tids[] = 0;
506 $query = db_query('SELECT DISTINCT(tid) FROM {term_access}');
507 while ($result = db_fetch_array($query)) {
508 $old_tids[] = $result['tid'];
509 }
510
511 if (!$old_rids) {
512 $query = db_query('SELECT DISTINCT(rid) FROM {term_access}');
513 while($result = db_fetch_array($query)) {
514 $old_rids[] = $result['rid'];
515 }
516 }
517 $old_vids = array();
518 $query = db_query('SELECT vid FROM {term_access_defaults}');
519 while($result = db_fetch_array($query)) {
520 $old_vids[] = $result['vid'];
521 }
522
523 // Get the difference between old and current
524 if (is_array($old_tids))
525 $delete_tids = array_diff($old_tids, $current_tids);
526 if (is_array($old_rids))
527 $delete_rids = array_diff($old_rids, $current_rids);
528 if (is_array($old_vids))
529 $delete_vids = array_diff($old_vids, $current_vids);
530
531 // Delete all rows with role and term ids that no longer exist from the term_access table
532 if (is_array($delete_rids)) {
533 foreach ($delete_rids as $rid) {
534 db_query('DELETE FROM {term_access} WHERE rid = %d', $rid);
535 }
536 }
537 foreach ($delete_tids as $tid) {
538 db_query('DELETE FROM {term_access} WHERE tid = %d', $tid);
539 }
540
541 // Set permissions for nodes without categories if they aren't already set
542 $query = db_query('SELECT tid FROM {term_access} where tid = 0');
543 if (!db_result($query) && is_array($current_rids)) {
544 foreach ($current_rids as $rid) {
545 $query = db_query('SELECT tid FROM {term_access} where tid=0 AND rid=%d', $rid);
546 if (!db_fetch_object($query)) {
547 db_query('INSERT INTO {term_access} VALUES (0, %d, 1, 0, 0, 1, 1)', $rid);
548 }
549 }
550 }
551
552 // Add new role and term ids to term_access table since module was last disabled and assign them default permissions
553 $all_rids = $add_tids = $add_rids = $add_vids = array();
554 $add_tids = array_diff($current_tids, $old_tids);
555 $add_vids = array_diff($current_vids, $old_vids);
556 if (is_array($current_rids) && is_array($old_rids)) {
557 $add_rids = array_diff($current_rids, $old_rids);
558 $all_rids = array_merge($add_rids, $current_rids);
559 }
560
561 // Add role permissions for each new taxonomy terms.
562 // nysus : Default permissions assume all users can not read content in the new taxonomy
563 // pyromanfo : Drupal default is actually view only, as is the case with node_access
564 foreach ($add_tids as $tid) {
565 if ($tid != 0) {
566 foreach ($all_rids as $rid) {
567 db_query('INSERT INTO {term_access} VALUES (%d, %d, 1, 0, 0, 1, 1)', $tid, $rid);
568 }
569 }
570 }
571
572 // Add role permissions for all old taxonomy terms.
573 // nysus : Default permissions assume new role does not have access to content in any category
574 // pyromanfo : Drupal default is actually view only, as is the case with node_access
575 foreach ($current_tids as $tid) {
576 if ($tid != 0) {
577 if (is_array($add_rids)) {
578 foreach ($add_rids as $rid) {
579 db_query('INSERT INTO {term_access} VALUES (%d, %d, 1, 0, 0, 1, 1)', $tid, $rid);
580 }
581 }
582 }
583 }
584 // END: term_access table housekeeping
585
586 // BEGIN: term_access_defaults housekeeping
587 // Setup defaults
588 if (is_array($delete_rids)) {
589 foreach ($delete_rids as $rid) {
590 db_query("DELETE FROM {term_access_defaults} WHERE rid='%d'",$rid);
591 }
592 }
593 if (is_array($delete_vids)) {
594 foreach ($delete_vids as $vid) {
595 db_query("DELETE FROM {term_access_defaults} WHERE vid='%d'",$vid);
596 }
597 }
598
599 if (is_array($current_vids)) {
600 foreach ($current_vids as $vid) {
601 if (is_array($add_rids)) {
602 foreach ($add_rids as $rid) {
603 db_query("DELETE FROM {term_access_defaults} WHERE vid=%d AND rid=%d", $vocab->vid, $rid);
604 db_query("INSERT INTO {term_access_defaults} VALUES (%d,%d,1,0,0,1,1)",$vocab->vid,$rid);
605 }
606 }
607 }
608 }
609
610 if (is_array($add_vids)) {
611 foreach ($add_vids as $vid) {
612 if (is_array($current_rids)) {
613 foreach ($current_rids as $rid) {
614 db_query("DELETE FROM {term_access_defaults} WHERE vid=%d AND rid=%d", $vocab->vid, $rid);
615 db_query("INSERT INTO {term_access_defaults} VALUES (%d,%d,1,0,0,1,1)",$vocab->vid,$rid);
616 }
617 }
618 }
619 }
620 // END: term_access_defaults housekeeping
621
622 // Force to rebuild node_access_table to reflect the changes made to term_access table
623 node_access_rebuild();
624 }
625
626 /**
627 * Implementation of hook_db_rewrite_sql()
628 */
629 function taxonomy_access_db_rewrite_sql($query, $table, $field) {
630 if (!user_access('administer taxonomy') && ($field =='vid' || $field =='tid')) {
631 global $user;
632 $op = (arg(0) == 'node' && (arg(1) == 'add' || arg(2) == 'edit')) ? 'create' : 'list';
633
634 // let's cache
635 static $taxonomy_access_sql_clause;
636 $clause = array();
637
638 if (!isset($taxonomy_access_sql_clause)) {
639 $taxonomy_access_sql_clause = array();
640 }
641 if (!isset($taxonomy_access_sql_clause[$op][$field])) {
642 if (isset($user) && is_array($user->roles)) {
643 $rids = array_keys($user->roles);
644 }
645 else {
646 $rids[] = 1;
647 }
648
649 $sql = db_query("SELECT t.tid, d.vid, BIT_OR(t.grant_$op) AS grant_$op FROM {term_access} t INNER JOIN {term_data} d ON t.tid=d.tid WHERE t.rid in ('".implode("','",$rids)."') AND grant_$op = 1 group by t.tid, d.vid");
650 while ($result = db_fetch_object($sql)) {
651 $tids[]= $result->tid;
652 $vids[$result->vid]= $result->vid;
653 }
654 $clause[$op]['tid'] = isset($tids) ? implode("','",$tids) : '';
655 $clause[$op]['vid']= isset($vids) ? implode("','",$vids) : '';
656 $taxonomy_access_sql_clause = $clause;
657 }
658 else {
659 $clause[$op][$field] = $taxonomy_access_sql_clause[$op][$field];
660 }
661 $return['where'] = ($clause[$op][$field]) ? "$table.$field IN ('".$clause[$op][$field]."')" : "$table.$field IS NULL";
662 return $return;
663 }
664 else {
665 return array();
666 }
667 }
668
669 /**
670 * used to preserve terms deleted by taxonomy_node_delete()
671 * that the user shouldn't have access to delete.
672 * see http://drupal.org/node/92355 and http://drupal.org/node/93086
673 *
674 * Called by hook_form_alter()
675 */
676 function taxonomy_access_preserve_terms($nid = FALSE) {
677
678 // prepare/cache return value
679 static $tids = array();
680
681 // a valid numeric nid is required
682 if (!is_numeric($nid)) {
683 return array();
684 }
685
686 // use cached values if possible
687 if (isset($tids[$nid])) {
688 return $tids[$nid];
689 }
690
691 // get a list of terms this user has access to/over
692 // (invokes hook_db_rewrite_sql() to limit access)
693 $user_terms = taxonomy_node_get_terms($nid);
694
695 // get a list of all terms this node is in regardless of user's
696 // access settings. Don't use db_rewrite_sql() api call here (or
697 // any other API call, the taxonomy API functions all use
698 // db_rewrite_sql() so we must query the database tables directly)
699 $result = db_query('SELECT tid FROM {term_node} WHERE nid = %d', $nid);
700 while ($row = db_fetch_array($result)) {
701 // only include those terms the current user does not have access to
702 if (!isset($user_terms[$row['tid']])) {
703 $tids[$nid][$row['tid']] = $row['tid'];
704 }
705 }
706
707 // return only terms current user does not have access
708 // to and therefore need restoring after edit/update
709 return $tids[$nid];
710 }
711
712 /**
713 * used to restore terms deleted by taxonomy_node_delete()
714 * that the user shouldn't have access to delete.
715 * see http://drupal.org/node/92355 and http://drupal.org/node/93086
716 *
717 * Called by taxonomy_access_nodeapi()
718 */
719 function taxonomy_access_restore_terms($nid, $protected_terms) {
720 if (isset($protected_terms)) {
721 $terms = $protected_terms;
722 if (count($terms)) {
723 db_query('DELETE FROM {term_node} WHERE nid = %d AND tid IN ('. implode(',', $terms). ')', $nid);
724 foreach ($terms as $tid) {
725 $replace_terms[] = '('.$nid.','.$tid.')';
726 }
727 db_query('INSERT INTO {term_node} (nid,tid) VALUES '. implode(',', $replace_terms));
728 }
729 }
730 }

  ViewVC Help
Powered by ViewVC 1.1.2