Projet

Général

Profil

Paste
Télécharger (44,4 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / nodeaccess / nodeaccess.module @ 0695d136

1
<?php
2

    
3
/**
4
 * @file
5
 * Provide per node access control
6
 */
7

    
8
/**
9
 * Implements hook_help().
10
 */
11
function nodeaccess_help($path, $arg) {
12
  switch ($path) {
13
    case 'node/%/grant':
14
      return t("You can set grants for individual users. Enter a name or a partial name in the box and click Search or press return. You must check the 'Keep?' checkbox if you want to keep the user for granting. Note that user grants are in addition to those coming from roles.");
15
  }
16
}
17

    
18
/**
19
 * Implements hook_menu().
20
 */
21
function nodeaccess_menu() {
22
  $items['admin/config/people/nodeaccess'] = array(
23
    'title' => 'Nodeaccess',
24
    'description' => 'Change default settings for the Nodeaccess module.',
25
    'page callback' => 'nodeaccess_admin',
26
    'access arguments' => array('administer nodeaccess'),
27
  );
28
  $items['node/%node/grant'] = array(
29
    'title' => 'Grant',
30
    'page callback' => 'nodeaccess_grants',
31
    'page arguments' => array(1),
32
    'access callback' => 'nodeaccess_access',
33
    'access arguments' => array('grant', 1),
34
    'weight' => 5,
35
    'type' => MENU_LOCAL_TASK,
36
  );
37
  return $items;
38
}
39

    
40
/**
41
 * Implements hook_admin_paths().
42
 */
43
function nodeaccess_admin_paths() {
44
  $paths = array(
45
    'node/*/grant' => TRUE,
46
    'admin/config/people/nodeaccess' => TRUE,
47
  );
48
  return $paths;
49
}
50

    
51
/**
52
 * Implements hook_permission().
53
 */
54
function nodeaccess_permission() {
55

    
56
  return array(
57
    'administer nodeaccess' => array(
58
      'title' => t('Administer Nodeaccess'),
59
    ),
60
    'grant node permissions' => array(
61
      'title' => t('Grant Node Permissions'),
62
    ),
63
    'grant editable node permissions' => array(
64
      'title' => t('Grant node edit permissions'),
65
    ),
66
    'grant deletable node permissions' => array(
67
      'title' => t('Grant node delete permissions'),
68
    ),
69
    'grant own node permissions' => array(
70
      'title' => t('Grant own node permissions'),
71
    ),
72
  );
73
}
74

    
75
/**
76
 * Implements hook_node_access().
77
 */
78
function nodeaccess_node_access($node, $op, $account) {
79
  switch ($op) {
80
    case 'update':
81
    case 'delete':
82
      if (!isset($account->uid)) {
83
        global $user;
84
        $account = $user;
85
      }
86
      // If the node belongs to a deleted user.
87
      if ($account->uid == 0 && $node->uid == 0) {
88
        // We check if the role has particular access to this node.
89
        $grants = _nodeaccess_get_grants($node);
90
        // If anonymous has rights to this node, we allow them.
91
        if (($grants['rid'][1]['grant_update'] && $op == 'update') ||
92
            ($grants['rid'][1]['grant_delete'] && $op == 'delete')) {
93
          return NODE_ACCESS_ALLOW;
94
        }
95
        return NODE_ACCESS_DENY;
96
      }
97
      break;
98

    
99
    case 'view':
100
      if (!isset($account->uid)) {
101
        global $user;
102
        $account = $user;
103
      }
104
      // If the node is not published. We check other permissions.
105
      if (!$node->status) {
106
        // If the current user is the author and not anonymous.
107
        if ($node->uid == $account->uid && $account->uid > 0) {
108
          // We check to see if they have access to view own unpublished.
109
          if (user_access('view own unpublished content') || user_access('bypass node access')) {
110
            return NODE_ACCESS_ALLOW;
111
          }
112
        }
113
        elseif (user_access('bypass node access')) {
114
          return NODE_ACCESS_ALLOW;
115
        }
116
        return NODE_ACCESS_IGNORE;
117
      }
118
      break;
119

    
120
  }
121
}
122

    
123
/**
124
 * Determine access to Grant tab.
125
 */
126
function nodeaccess_access($op, $node, $account = NULL) {
127
  global $user;
128
  if (!$node) {
129
    return FALSE;
130
  }
131

    
132
  // Apparently D7 no longer defaults to admin getting anything?
133
  if (user_access('administer nodeaccess')) {
134
    return TRUE;
135
  }
136

    
137
  // If no user object is supplied, the access check is for the current user.
138
  if (empty($account)) {
139
    $account = $user;
140
  }
141
  $allowed_types = variable_get('nodeaccess-types', array());
142
  if ($op == 'grant') {
143
    if ($node->nid && isset($allowed_types[$node->type]) && !empty($allowed_types[$node->type]) &&
144
        (user_access('grant node permissions', $account) ||
145
         (user_access('grant editable node permissions', $account) && node_access('update', $node, $account)) ||
146
         (user_access('grant deletable node permissions', $account) && node_access('delete', $node, $account)) ||
147
         (user_access('grant own node permissions', $account) && ($account->uid == $node->uid)))) {
148
      return TRUE;
149
    }
150
  }
151
  return FALSE;
152
}
153

    
154
/**
155
 * Implements hook_theme().
156
 */
157
function nodeaccess_theme($existing, $type, $theme, $path) {
158
  return array(
159
    'nodeaccess_admin_form_roles' => array(
160
      'render element'  => 'form',
161
    ),
162
    'nodeaccess_admin_form_types' => array(
163
      'render element'  => 'form',
164
    ),
165
    'nodeaccess_grants_form'  => array(
166
      'render element'  => 'form',
167
    ),
168
  );
169
}
170

    
171
/**
172
 * Menu callback. Draws the admin page.
173
 */
174
function nodeaccess_admin() {
175
  return drupal_get_form('nodeaccess_admin_form');
176
}
177

    
178

    
179
/**
180
 * Menu callback. Draws the admin page.
181
 */
182
function nodeaccess_admin_form($form, $form_state) {
183
  // Set defaults from variable_get.
184
  $show = variable_get('nodeaccess-types', array());
185
  $roles = nodeaccess_get_role_aliases();
186
  $allowed_roles = variable_get('nodeaccess-roles', array());
187
  $allowed_grants = variable_get('nodeaccess-grants', array());
188

    
189
  $form['priority'] = array(
190
    '#type' => 'checkbox',
191
    '#title' => t('Give node grants priority'),
192
    '#default_value' => variable_get('nodeaccess-priority', 0),
193
    '#description' => t('If you are only using this access control module, you can safely ignore this. If you are using multiple access control modules, and you want the grants given on individual nodes to override any grants given by other modules, you should check this box.'),
194
  );
195

    
196
  // Select whether to preserve hidden grants.
197
  $form['preserve'] = array(
198
    '#type' => 'checkbox',
199
    '#title' => t('Preserve hidden grants'),
200
    '#default_value' => variable_get('nodeaccess-preserve', 1),
201
    '#description' => '<small>' . t('If you check this box, any hidden grants are preserved when you save grants. Otherwise all grants users are not allowed to view or edit are revoked on save.') . '</small>',
202
  );
203

    
204
  // Select permissions you want to allow users to view and edit.
205
  $form['grant'] = array(
206
    '#type' => 'fieldset',
207
    '#collapsible' => TRUE,
208
    '#collapsed' => TRUE,
209
    '#title' => t('Allowed Grants'),
210
    '#tree' => TRUE,
211
    '#description' => '<small>' . t('The selected grants will be listed on individual node grants. If you wish for certain grants to be hidden from users on the node grants tab, make sure they are not selected here.') . '</small>',
212
  );
213
  $form['grant']['view'] = array(
214
    '#type' => 'checkbox',
215
    '#title' => t('View'),
216
    '#default_value' => $allowed_grants['view'],
217
  );
218
  $form['grant']['edit'] = array(
219
    '#type' => 'checkbox',
220
    '#title' => t('Edit'),
221
    '#default_value' => $allowed_grants['edit'],
222
  );
223
  $form['grant']['delete'] = array(
224
    '#type' => 'checkbox',
225
    '#title' => t('Delete'),
226
    '#default_value' => $allowed_grants['delete'],
227
  );
228

    
229
  // Select roles the permissions of which you want to allow users to
230
  // view and edit, and the aliases and weights of those roles.
231
  $form['role'] = array(
232
    '#type' => 'fieldset',
233
    '#collapsible' => TRUE,
234
    '#collapsed' => TRUE,
235
    '#title' => t('Allowed Roles'),
236
    '#tree' => TRUE,
237
    '#theme' => 'nodeaccess_admin_form_roles',
238
    '#description' => t('The selected roles will be listed on individual node grants. If you wish for certain roles to be hidden from users on the node grants tab, make sure they are not selected here. You may also provide an alias for each role to be displayed to the user and a weight to order them by. This is useful if your roles have machine-readable names not intended for human users.'),
239
  );
240

    
241
  foreach ($roles as $id => $role) {
242
    // Catch NULL values.
243
    if (!$role['alias']) {
244
      $role['alias'] = '';
245
    }
246
    if (!$role['weight']) {
247
      $role['weight'] = 0;
248
    }
249
    $form['role'][$id]['name'] = array(
250
      '#type' => 'hidden',
251
      '#value' => $role['name'],
252
    );
253
    $form['role'][$id]['allow'] = array(
254
      '#type' => 'checkbox',
255
      '#title' => check_plain($role['name']),
256
      '#default_value' => isset($allowed_roles[$id]) ? $allowed_roles[$id] : 0,
257
    );
258
    $form['role'][$id]['alias'] = array(
259
      '#type' => 'textfield',
260
      '#default_value' => $role['alias'],
261
      '#size' => 50,
262
      '#maxlength' => 50,
263
    );
264
    $form['role'][$id]['weight'] = array(
265
      '#type' => 'weight',
266
      '#default_value' => $role['weight'],
267
      '#delta' => 10,
268
    );
269
  }
270

    
271
  // Generate fieldsets for each node type.
272
  foreach (node_type_get_types() as $type => $bundle) {
273
    $form['nodeaccess'][$type] = array(
274
      '#type' => 'fieldset',
275
      '#collapsible' => TRUE,
276
      '#collapsed' => TRUE,
277
      '#title' => check_plain($bundle->name),
278
      '#tree' => TRUE,
279
      '#theme' => 'nodeaccess_admin_form_types',
280
    );
281

    
282
    $form['nodeaccess'][$type]['show'] = array(
283
      '#type' => 'checkbox',
284
      '#title' => t('Show grant tab for this node type'),
285
      '#default_value' => isset($show[$type]) ? $show[$type] : 0,
286
    );
287

    
288
    // Set default author permissions for node type.
289
    $author_prefs = variable_get('nodeaccess_authors', array());
290
    $form['nodeaccess'][$type]['author']['grant_view'] = array(
291
      '#type' => 'checkbox',
292
      '#default_value' => $author_prefs[$type]['grant_view'],
293
    );
294
    $form['nodeaccess'][$type]['author']['grant_update'] = array(
295
      '#type' => 'checkbox',
296
      '#default_value' => $author_prefs[$type]['grant_update'],
297
    );
298
    $form['nodeaccess'][$type]['author']['grant_delete'] = array(
299
      '#type' => 'checkbox',
300
      '#default_value' => $author_prefs[$type]['grant_delete'],
301
    );
302

    
303
    $perms = variable_get('nodeaccess_' . $type, array());
304
    foreach ($perms as $perm) {
305
      $opts[$perm['gid']] = $perm;
306
    }
307

    
308
    // Set default role permissions for node type.
309
    foreach (user_roles() as $id => $role) {
310
      $form['nodeaccess'][$type]['roles'][$id]['name'] = array('#markup' => $role);
311
      $form['nodeaccess'][$type]['roles'][$id]['grant_view'] = array(
312
        '#type' => 'checkbox',
313
        '#default_value' => isset($opts[$id]['grant_view']) ? $opts[$id]['grant_view'] : 0,
314
      );
315
      $form['nodeaccess'][$type]['roles'][$id]['grant_update'] = array(
316
        '#type' => 'checkbox',
317
        '#default_value' => isset($opts[$id]['grant_update']) ? $opts[$id]['grant_update'] : 0,
318
      );
319
      $form['nodeaccess'][$type]['roles'][$id]['grant_delete'] = array(
320
        '#type' => 'checkbox',
321
        '#default_value' => isset($opts[$id]['grant_delete']) ? $opts[$id]['grant_delete'] : 0,
322
      );
323
    }
324

    
325
    // Set the default permissions if userreference exists and is enabled on
326
    // the content type.
327
    if (module_exists('user_reference')) {
328
      $bundle = field_extract_bundle('node', $bundle);
329
      $fields = field_info_instances('node', $bundle);
330
      $user_reference_perms = variable_get('nodeaccess_' . $type . '_user_reference', array());
331

    
332
      $field_types = field_info_field_types();
333

    
334
      foreach ($fields as $field) {
335
        $field = field_info_field($field['field_name']);
336
        if ($field['type'] == 'user_reference') {
337
          $enabled = isset($user_reference_perms[$field['field_name']]['enabled']) ? $user_reference_perms[$field['field_name']]['enabled'] : 0;
338
          $view = isset($user_reference_perms[$field['field_name']]['grant_view']) ? $user_reference_perms[$field['field_name']]['grant_view'] : 0;
339
          $update = isset($user_reference_perms[$field['field_name']]['grant_update']) ? $user_reference_perms[$field['field_name']]['grant_update'] : 0;
340
          $delete = isset($user_reference_perms[$field['field_name']]['grant_delete']) ? $user_reference_perms[$field['field_name']]['grant_delete'] : 0;
341

    
342
          $form['nodeaccess'][$type]['user_reference'][$field['field_name']]['name'] = array('#value' => t($field_types[$field['type']]['label']));
343
          $form['nodeaccess'][$type]['user_reference'][$field['field_name']]['enabled'] = array(
344
            '#type' => 'checkbox',
345
            '#default_value' => $enabled,
346
          );
347
          $form['nodeaccess'][$type]['user_reference'][$field['field_name']]['grant_view'] = array(
348
            '#type' => 'checkbox',
349
            '#default_value' => $view,
350
          );
351
          $form['nodeaccess'][$type]['user_reference'][$field['field_name']]['grant_update'] = array(
352
            '#type' => 'checkbox',
353
            '#default_value' => $update,
354
          );
355
          $form['nodeaccess'][$type]['user_reference'][$field['field_name']]['grant_delete'] = array(
356
            '#type' => 'checkbox',
357
            '#default_value' => $delete,
358
          );
359
        }
360
      }
361
    }
362
  }
363
  $form['submit'] = array(
364
    '#type' => 'submit',
365
    '#value' => t('Save Grants'),
366
  );
367
  return $form;
368
}
369

    
370
/**
371
 * Submit function for nodeaccess_admin_form.
372
 */
373
function nodeaccess_admin_form_submit($form, $form_state) {
374
  $form_values = $form_state['values'];
375
  // Save priority.
376
  variable_set('nodeaccess-priority', $form_values['priority']);
377
  // Save preserve.
378
  variable_set('nodeaccess-preserve', $form_values['preserve']);
379
  // Save allowed grants.
380
  foreach ($form_values['grant'] as $id => $val) {
381
    $allowed_grants[$id] = $val;
382
  }
383
  variable_set('nodeaccess-grants', $allowed_grants);
384
  // Save allowed roles, role aliases and weights.
385
  $alias_prefs = array();
386
  $allowed_roles = array();
387
  foreach ($form_values['role'] as $id => $val) {
388
    $allowed_roles[$id] = $val['allow'];
389
    // Save alias and weight only for allowed roles.
390
    if ($val['allow']) {
391
      // If alias is empty, default to role name.
392
      if ($val['alias']) {
393
        $alias_prefs[$id]['name'] = $val['alias'];
394
      }
395
      else {
396
        $alias_prefs[$id]['name'] = $val['name'];
397
      }
398
      $alias_prefs[$id]['weight'] = $val['weight'];
399
    }
400
    else {
401
      // Otherwise, we only save alias if one was specified.
402
      if ($val['alias']) {
403
        $alias_prefs[$id]['name'] = $val['alias'];
404
        $alias_prefs[$id]['weight'] = $val['weight'];
405
      }
406
    }
407
  }
408
  variable_set('nodeaccess-roles', $allowed_roles);
409
  nodeaccess_save_role_aliases($alias_prefs);
410
  // Save author and role permissions for each node type.
411
  $author_prefs = array();
412
  foreach (node_type_get_types() as $type => $name) {
413
    $grants = array();
414
    foreach ($form_values[$type]['roles'] as $role => $val) {
415
      $grants[] = array(
416
        'gid' => $role,
417
        'realm' => 'nodeaccess_rid',
418
        'grant_view' => $val['grant_view'],
419
        'grant_update' => $val['grant_update'],
420
        'grant_delete' => $val['grant_delete'],
421
      );
422
    }
423
    variable_set('nodeaccess_' . $type, $grants);
424
    if ($form_values[$type]['show']) {
425
      $allowed_types[$type] = 1;
426
    }
427
    else {
428
      $allowed_types[$type] = 0;
429
    }
430
    $author_prefs[$type] = $form_values[$type]['author'];
431
    // Also save userreference default permissions if enabled.
432
    if (module_exists('user_reference') && isset($form_values[$type]['user_reference'])) {
433
      $user_reference_grants = array();
434
      foreach ($form_values[$type]['user_reference'] as $user_reference_field => $val) {
435
        $user_reference_grants[$user_reference_field] = array(
436
          'gid' => 'nodeaccess_uid',
437
          'enabled' => $val['enabled'],
438
          'grant_view' => $val['grant_view'],
439
          'grant_update' => $val['grant_update'],
440
          'grant_delete' => $val['grant_delete'],
441
        );
442
      }
443
      variable_set('nodeaccess_' . $type . '_user_reference', $user_reference_grants);
444
    }
445
  }
446
  variable_set('nodeaccess_authors', $author_prefs);
447
  // Save allowed node types.
448
  variable_set('nodeaccess-types', $allowed_types);
449
  node_access_needs_rebuild(TRUE);
450
  drupal_set_message(t('Grants saved.'));
451
}
452

    
453
/**
454
 * Theme function for nodeaccess_admin_form.
455
 */
456
function theme_nodeaccess_admin_form_roles($variables) {
457
  $output = '';
458
  $form = $variables['form'];
459
  $rows = array();
460
  foreach (element_children($form) as $rid) {
461
    // Classify the weight element for TableDrag.
462
    $form[$rid]['weight']['#attributes']['class'] = array('roles-order-weight');
463

    
464
    // Mark the table row as draggable for TableDrag.
465
    $row = array(
466
      'data' => array(),
467
      'class' => array('draggable'),
468
    );
469
    // Render the table columns.
470
    $row['data'][] = drupal_render($form[$rid]['allow']);
471
    $row['data'][] = drupal_render($form[$rid]['alias']);
472
    $row['data'][] = drupal_render($form[$rid]['weight']);
473
    $rows[] = $row;
474
  }
475

    
476
  $header = array(t('Allow Role'), t('Alias'), t('Weight'));
477
  $output .= theme('table', array(
478
    'header' => $header,
479
    'rows' => $rows,
480
    'attributes' => array('id' => 'roles-order'),
481
  ));
482
  $output .= drupal_render_children($form);
483

    
484
  // Attach TableDrag to the table ID and contained weight elements.
485
  drupal_add_tabledrag('roles-order', 'order', 'sibling', 'roles-order-weight');
486

    
487
  return $output;
488
}
489

    
490
/**
491
 * Output the grant table.
492
 * @todo Please document this function.
493
 * @see http://drupal.org/node/1354
494
 */
495
function theme_nodeaccess_admin_form_types($variables) {
496
  // @todo Number of parameters does not match hook_theme.
497
  $form = $variables['form'];
498
  $output = drupal_render($form['show']);
499
  $roles = element_children($form['roles']);
500
  $header = array(t('Role'), t('View'), t('Edit'), t('Delete'));
501
  foreach ($roles as $role) {
502
    $row = array();
503
    $row[] = drupal_render($form['roles'][$role]['name']);
504
    $row[] = drupal_render($form['roles'][$role]['grant_view']);
505
    $row[] = drupal_render($form['roles'][$role]['grant_update']);
506
    $row[] = drupal_render($form['roles'][$role]['grant_delete']);
507
    $rows[] = $row;
508
  }
509
  $output .= theme('table', array('header' => $header, 'rows' => $rows));
510
  $header = array(t('Author Settings'), t('View'), t('Edit'), t('Delete'));
511
  $row = array();
512
  $row[] = t('Node author');
513
  $row[] = drupal_render($form['author']['grant_view']);
514
  $row[] = drupal_render($form['author']['grant_update']);
515
  $row[] = drupal_render($form['author']['grant_delete']);
516

    
517
  $output .= theme('table', array('header' => $header, 'rows' => array($row)));
518

    
519
  $output .= '<small>' . t('The settings selected for the node author will define what permissions the node author has. This cannot be changed on individual node grants.') . '</small>';
520

    
521
  if (module_exists('user_reference') && isset($form['user_reference'])) {
522
    $user_reference_fields = element_children($form['user_reference']);
523
    $header = array(t('User Reference Field'),
524
      t('Enable this field'),
525
      t('View'),
526
      t('Edit'),
527
      t('Delete'),
528
    );
529
    $rows = array();
530
    foreach ($user_reference_fields as $user_reference_field) {
531
      $row = array();
532

    
533
      $row[] = $form['user_reference'][$user_reference_field]['name']['#value'];
534
      $row[] = drupal_render($form['user_reference'][$user_reference_field]['enabled']);
535
      $row[] = drupal_render($form['user_reference'][$user_reference_field]['grant_view']);
536
      $row[] = drupal_render($form['user_reference'][$user_reference_field]['grant_update']);
537
      $row[] = drupal_render_children($form['user_reference'][$user_reference_field]['grant_delete']);
538
      $rows[] = $row;
539
    }
540
    $output .= theme('table', array(
541
        'header' => $header,
542
        'rows' => $rows,
543
      ));
544
    $output .= '<small>' . t('If enabled, the value of the user reference field will be granted the associated permissions. If a user changes the value of the user reference field on a node, the associated user will be modified in the node-specific access table.') . '</small>';
545
  }
546
  return $output;
547
}
548

    
549
/**
550
 * Menu callback. Draws the grant tab.
551
 */
552
function nodeaccess_grants($node) {
553
  return drupal_get_form('nodeaccess_grants_form', $node);
554
}
555

    
556
/**
557
 * Menu callback. Draws the grant tab.
558
 */
559
function nodeaccess_grants_form($form, &$form_state, $node) {
560
  $form_values = &$form_state['values'];
561
  if (!$form_values) {
562
    $form_values = array();
563
    // Load all roles.
564
    $result = db_query("SELECT r.rid, nra.name, na.grant_view, na.grant_update, na.grant_delete
565
      FROM {role} r
566
      LEFT JOIN {nodeaccess_role_alias} nra ON r.rid = nra.rid
567
      LEFT JOIN {node_access} na ON r.rid = na.gid AND na.realm = :realm AND na.nid = :nid
568
      ORDER BY nra.weight, nra.name", array(':realm' => 'nodeaccess_rid', ':nid' => $node->nid));
569
    foreach ($result as $grant) {
570
      $form_values['rid'][$grant->rid] = array(
571
        'name' => $grant->name,
572
        'grant_view' => (boolean) $grant->grant_view,
573
        'grant_update' => (boolean) $grant->grant_update,
574
        'grant_delete' => (boolean) $grant->grant_delete,
575
      );
576
    }
577
    // Load users from node_access.
578
    $results = db_query("SELECT uid, name, grant_view, grant_update, grant_delete
579
      FROM {node_access}
580
      LEFT JOIN {users} ON uid = gid
581
      WHERE nid = :nid AND realm = :realm
582
      ORDER BY name", array(
583
        ':nid' => $node->nid,
584
        ':realm' => 'nodeaccess_uid',
585
      ));
586
    foreach ($results as $account) {
587
      $form_values['uid'][$account->uid] = array(
588
        'name' => $account->name,
589
        'keep' => 1,
590
        'grant_view' => $account->grant_view,
591
        'grant_update' => $account->grant_update,
592
        'grant_delete' => $account->grant_delete,
593
      );
594
    }
595
  }
596
  else {
597
    // Perform search.
598
    if ($form_values['keys']) {
599
      // @todo rewrite
600
      $params = array();
601
      $sql = "SELECT uid, name FROM {users} WHERE name LIKE :name";
602
      $name = preg_replace('!\*+!', '%', $form_values['keys']);
603
      $params[':name'] = $name;
604
      $users = '';
605
      if (isset($form_values['uid']) && is_array($form_values['uid'])) {
606
        $sql .= ' AND uid NOT IN (:uid)';
607
        $users = implode(',', array_keys($form_values['uid']));
608
        $params[':uid'] = $users;
609
      }
610

    
611
      $result = db_query($sql, $params);
612
      foreach ($result as $account) {
613

    
614
        $form_values['uid'][$account->uid] = array(
615
          'name' => $account->name,
616
          'keep' => 0,
617
        );
618
      }
619
    }
620
    // Calculate default grants for found users.
621
    // rewrite
622
    if (isset($form_values['uid']) && is_array($form_values['uid'])) {
623
      foreach (array_keys($form_values['uid']) as $uid) {
624
        if (!$form_values['uid'][$uid]['keep']) {
625
          foreach (array('grant_view', 'grant_update', 'grant_delete') as $grant_type) {
626
            $form_values['uid'][$uid][$grant_type] = db_query_range("SELECT count(*) FROM {node_access} na LEFT JOIN {users_roles} r ON na.gid = r.rid WHERE nid = :nid AND realm = :realm AND uid = :uid AND $grant_type = 1",
627
              0, 1,
628
              array(
629
                ':nid' => $node->nid,
630
                ':realm' => 'nodeaccess_rid',
631
                ':uid' => $uid,
632
              ))->fetchField() ||
633
              db_query_range("SELECT count(*) FROM {node_access} na WHERE nid = :nid AND realm = :realm AND gid = :gid AND $grant_type = 1",
634
                0, 1,
635
                array(
636
                  ':nid' => $node->nid,
637
                  ':realm' => 'nodeaccess_uid',
638
                  ':gid' => $uid,
639
                )
640
                )->fetchField();
641
          }
642
          $form_values['uid'][$uid]['keep'] = TRUE;
643
        }
644
      }
645
    }
646
  }
647
  if (!isset($form_values['rid'])) {
648
    $form_values['rid'] = array();
649
  }
650

    
651
  if (!isset($form_values['uid'])) {
652
    $form_values['uid'] = array();
653
  }
654

    
655
  $roles = $form_values['rid'];
656
  $users = $form_values['uid'];
657

    
658
  $form['nid'] = array(
659
    '#type' => 'hidden',
660
    '#value' => $node->nid,
661
  );
662

    
663
  $allowed_roles = variable_get('nodeaccess-roles', array());
664
  $allowed_grants = variable_get('nodeaccess-grants', array());
665
  // If $preserve is TRUE, the fields the user is not allowed to view or
666
  // edit are included in the form as hidden fields to preserve them.
667
  $preserve = variable_get('nodeaccess-preserve', 1);
668

    
669
  // Roles table.
670
  if (is_array($roles)) {
671
    $form['rid'] = array('#tree' => TRUE);
672
    foreach ($roles as $key => $field) {
673
      if (isset($allowed_roles[$key]) && $allowed_roles[$key]) {
674
          $form['rid'][$key]['name'] = array(
675
            '#type' => 'hidden',
676
            '#value' => $field['name'],
677
          );
678
          if ($allowed_grants['view']) {
679
            $form['rid'][$key]['grant_view'] = array(
680
              '#type' => 'checkbox',
681
              '#default_value' => $field['grant_view'],
682
            );
683
          }
684
          elseif ($preserve) {
685
            $form['rid'][$key]['grant_view'] = array(
686
              '#type' => 'hidden',
687
              '#value' => $field['grant_view'],
688
            );
689
          }
690
          if ($allowed_grants['edit']) {
691
            $form['rid'][$key]['grant_update'] = array(
692
              '#type' => 'checkbox',
693
              '#default_value' => $field['grant_update'],
694
            );
695
          }
696
          elseif ($preserve) {
697
            $form['rid'][$key]['grant_update'] = array(
698
              '#type' => 'hidden',
699
              '#value' => $field['grant_update'],
700
            );
701
          }
702
          if ($allowed_grants['delete']) {
703
            $form['rid'][$key]['grant_delete'] = array(
704
              '#type' => 'checkbox',
705
              '#default_value' => $field['grant_delete'],
706
            );
707
          }
708
          elseif ($preserve) {
709
            $form['rid'][$key]['grant_delete'] = array(
710
              '#type' => 'hidden',
711
              '#value' => $field['grant_delete'],
712
            );
713
          }
714
      }
715
      elseif ($preserve) {
716
        $form['rid'][$key]['name'] = array(
717
          '#type' => 'hidden',
718
          '#value' => $field['name'],
719
        );
720
        $form['rid'][$key]['grant_view'] = array(
721
          '#type' => 'hidden',
722
          '#value' => $field['grant_view'],
723
        );
724
        $form['rid'][$key]['grant_update'] = array(
725
          '#type' => 'hidden',
726
          '#value' => $field['grant_update'],
727
        );
728
        $form['rid'][$key]['grant_delete'] = array(
729
          '#type' => 'hidden',
730
          '#value' => $field['grant_delete'],
731
        );
732
      }
733
    }
734
  }
735

    
736
  // Users table.
737
  if (is_array($users)) {
738
    $form['uid'] = array('#tree' => TRUE);
739
    foreach ($users as $key => $field) {
740
      $form['uid'][$key]['name'] = array(
741
        '#type' => 'hidden',
742
        '#value' => $field['name'],
743
      );
744
      $form['uid'][$key]['keep'] = array(
745
        '#type' => 'checkbox',
746
        '#default_value' => $field['keep'],
747
      );
748
      if ($allowed_grants['view']) {
749
        $form['uid'][$key]['grant_view'] = array(
750
          '#type' => 'checkbox',
751
          '#default_value' => $field['grant_view'],
752
        );
753
      }
754
      elseif ($preserve) {
755
        $form['uid'][$key]['grant_view'] = array(
756
          '#type' => 'hidden',
757
          '#value' => $field['grant_view'],
758
        );
759
      }
760
      if ($allowed_grants['edit']) {
761
        $form['uid'][$key]['grant_update'] = array(
762
          '#type' => 'checkbox',
763
          '#default_value' => $field['grant_update'],
764
        );
765
      }
766
      elseif ($preserve) {
767
        $form['uid'][$key]['grant_update'] = array(
768
          '#type' => 'hidden',
769
          '#value' => $field['grant_update'],
770
        );
771
      }
772
      if ($allowed_grants['delete']) {
773
        $form['uid'][$key]['grant_delete'] = array(
774
          '#type' => 'checkbox',
775
          '#default_value' => $field['grant_delete'],
776
        );
777
      }
778
      elseif ($preserve) {
779
        $form['uid'][$key]['grant_delete'] = array(
780
          '#type' => 'hidden',
781
          '#value' => $field['grant_delete'],
782
        );
783
      }
784
    }
785
  }
786

    
787
  // Autocomplete returns errors if users don't have access to profiles.
788
  if (user_access('access user profiles')) {
789
    $form['keys'] = array(
790
      '#type' => 'textfield',
791
      '#default_value' => isset($form_values['keys']) ? $form_values['keys'] : '',
792
      '#size' => 40,
793
      '#autocomplete_path' => 'user/autocomplete',
794
    );
795
  }
796
  else {
797
    $form['keys'] = array(
798
      '#type' => 'textfield',
799
      '#default_value' => isset($form_values['keys'])? $form_values['keys'] : '',
800
      '#size' => 40,
801
    );
802
  }
803

    
804
  $form['search'] = array(
805
    '#type' => 'submit',
806
    '#value' => t('Search'),
807
  );
808

    
809
  $form['submit'] = array(
810
    '#type' => 'submit',
811
    '#value' => t('Save Grants'),
812
  );
813
  return $form;
814
}
815

    
816
/**
817
 * Validate function for nodeaccess_grants_form.
818
 */
819
function nodeaccess_grants_form_validate($form, $form_state) {
820
  $form_values = &$form_state['values'];
821
  // Delete unkept users.
822
  if (isset($form_values['uid']) && is_array($form_values['uid'])) {
823
    foreach ($form_values['uid'] as $uid => $row) {
824
      if (!$row['keep']) {
825
        unset($form_values['uid'][$uid]);
826
      }
827
    }
828
  }
829
  if (!isset($form_values['uid'])) {
830
    unset($form_values['uid']);
831
  }
832

    
833
}
834

    
835
/**
836
 * Submit function for nodeaccess_grants_form.
837
 */
838
function nodeaccess_grants_form_submit($form, &$form_state) {
839

    
840
  if ($form_state['clicked_button']['#id'] == 'edit-search') {
841
    $form_state['rebuild'] = TRUE;
842
    $form_state['storage']['values'] = $form_state['values'];
843
  }
844
  else {
845
    unset($form_state['rebuild']);
846
    _nodeaccess_grants_form_submit($form, $form_state);
847
    drupal_set_message(t('Grants saved.'));
848
  }
849
}
850

    
851
/**
852
 * Private function to submit the per-node grants table.
853
 */
854
function _nodeaccess_grants_form_submit($form, $form_state) {
855
  $form_values = &$form_state['values'];
856
  global $user;
857
  $grants = array();
858
  $nid = $form_values['nid'];
859
  $node = node_load($nid);
860
  foreach (array('uid', 'rid') as $type) {
861
    $realm = 'nodeaccess_' . $type;
862
    if (isset($form_values[$type]) && is_array($form_values[$type])) {
863
      foreach ($form_values[$type] as $gid => $line) {
864
        $grant = array(
865
          'gid' => $gid,
866
          'realm' => $realm,
867
          'grant_view' => empty($line['grant_view']) ? 0 : $line['grant_view'],
868
          'grant_update' => empty($line['grant_update']) ? 0 : $line['grant_update'],
869
          'grant_delete' => empty($line['grant_delete']) ? 0 : $line['grant_delete'],
870
        );
871
        if ($grant['grant_view'] || $grant['grant_update'] || $grant['grant_delete']) {
872
          $grants[] = $grant;
873
        }
874
      }
875
    }
876
    node_access_write_grants($node, $grants, $realm);
877
  }
878

    
879
  // Save role and user grants to our own table.
880
  db_delete('nodeaccess')
881
  ->condition('nid', $nid)
882
  ->execute();
883
  foreach ($grants as $grant) {
884
    $id = db_insert('nodeaccess')
885
        ->fields(array(
886
          'nid' => $nid,
887
          'gid' => $grant['gid'],
888
          'realm' => $grant['realm'],
889
          'grant_view' => $grant['grant_view'],
890
          'grant_update' => $grant['grant_update'],
891
          'grant_delete' => $grant['grant_delete'],
892
        ))
893
    ->execute();
894
  }
895
}
896

    
897
/**
898
 * Theme function for nodeaccess_grants_form.
899
 */
900
function theme_nodeaccess_grants_form($variables) {
901
  $output = '';
902
  // @todo: Number of parameters in this theme function does not match number
903
  // of parameters found in hook_theme.
904
  $form = $variables['form'];
905
  $rows = array();
906
  $allowed_roles = variable_get('nodeaccess-roles', array());
907
  $allowed_grants = variable_get('nodeaccess-grants', array());
908
  // Retrieve role names for columns.
909
  $role_names = user_roles();
910
  $role_aliases = nodeaccess_get_role_aliases();
911

    
912
  // Replace names with aliases.
913
  foreach ($role_names as $rid => $name) {
914
    if (isset($role_aliases[$rid]['alias'])) {
915
      $role_names[$rid] = $role_aliases[$rid]['alias'];
916
    }
917
  }
918

    
919
  // Roles table.
920
  $roles = element_children($form['rid']);
921
  if (count($roles) && count($allowed_roles)) {
922
    $header = array();
923
    $header[] = t('Role');
924
    if ($allowed_grants['view']) {
925
      $header[] = t('View');
926
    }
927
    if ($allowed_grants['edit']) {
928
      $header[] = t('Edit');
929
    }
930
    if ($allowed_grants['delete']) {
931
      $header[] = t('Delete');
932
    }
933
    foreach ($roles as $key) {
934
      if (isset($allowed_roles[$key]) && $allowed_roles[$key]) {
935
        $row = array();
936
        $row[] = $role_names[$key] . drupal_render($form['rid'][$key]['name']);
937
        if ($allowed_grants['view']) {
938
          $row[] = drupal_render($form['rid'][$key]['grant_view']);
939
        }
940
        if ($allowed_grants['edit']) {
941
          $row[] = drupal_render($form['rid'][$key]['grant_update']);
942
        }
943
        if ($allowed_grants['delete']) {
944
          $row[] = drupal_render($form['rid'][$key]['grant_delete']);
945
        }
946
        $rows[] = $row;
947
      }
948
    }
949
    $output .= theme('table', array('header' => $header, 'rows' => $rows));
950
  }
951

    
952
  // Search form.
953
  $output .= '<p><div class="search-form">';
954
  $output .= '<strong>' . t('Enter names to search for users:') . '</strong>';
955
  $output .= '<div class="container-inline">';
956
  $output .= drupal_render($form['keys']);
957
  $output .= drupal_render($form['search']);
958
  $output .= '</div></div></p>';
959

    
960
  // Users table.
961
  unset($rows);
962
  $users = element_children($form['uid']);
963
  if (count($users) > 0) {
964
    $header = array();
965
    $rows = array();
966
    $header[] = t('User');
967
    $header[] = t('Keep?');
968
    if ($allowed_grants['view']) {
969
      $header[] = t('View');
970
    }
971
    if ($allowed_grants['edit']) {
972
      $header[] = t('Edit');
973
    }
974
    if ($allowed_grants['delete']) {
975
      $header[] = t('Delete');
976
    }
977
    foreach ($users as $key) {
978
      $row = array();
979
      $row[] = $form['uid'][$key]['name']['#value'];
980
      $row[] = drupal_render($form['uid'][$key]['keep']);
981
      if ($allowed_grants['view']) {
982
        $row[] = drupal_render($form['uid'][$key]['grant_view']);
983
      }
984
      if ($allowed_grants['edit']) {
985
        $row[] = drupal_render($form['uid'][$key]['grant_update']);
986
      }
987
      if ($allowed_grants['delete']) {
988
        $row[] = drupal_render($form['uid'][$key]['grant_delete']);
989
      }
990
      $rows[] = $row;
991
    }
992
    $output .= theme('table', array('header' => $header, 'rows' => $rows));
993
  }
994

    
995
  $output .= drupal_render_children($form);
996

    
997
  return $output;
998
}
999

    
1000
/**
1001
 * Implements hook_node_grants().
1002
 */
1003
function nodeaccess_node_grants($account, $op) {
1004
  $roles = is_array($account->roles) ? array_keys($account->roles) : array(-1);
1005
  return array(
1006
    'nodeaccess_rid' => $roles,
1007
    'nodeaccess_uid' => array($account->uid),
1008
    'nodeaccess_author' => array($account->uid),
1009
  );
1010
}
1011

    
1012
/**
1013
 * Implements hook_node_update().
1014
 */
1015
function nodeaccess_node_update($node) {
1016
  // Node author may have changed, overwrite old record.
1017
  $author_prefs = variable_get('nodeaccess_authors', array());
1018
  // Array is prepopulated with grant values.
1019
  $grant = $author_prefs[$node->type];
1020
  $grant['gid'] = $node->uid;
1021
  $grant['realm'] = 'nodeaccess_author';
1022
  $grants = array();
1023
  $grants[] = $grant;
1024
  node_access_write_grants($node, $grants, 'nodeaccess_author');
1025
  if (module_exists('user_reference')) {
1026
    $fields = variable_get('nodeaccess_' . $node->type . '_user_reference', array());
1027
    foreach (array_keys($fields) as $field_name) {
1028
      if (isset($node->$field_name)) {
1029
        $old_node = node_load($node->nid);
1030
        // Delete the old user as it's changed.
1031
        if ($node->$field_name != $old_node->$field_name) {
1032
          nodeaccess_delete_user_reference($old_node);
1033
          nodeaccess_insert_user_reference($node);
1034
        }
1035
        break;
1036
      }
1037
    }
1038
  }
1039
  // Done, author permissions are not written into nodeaccess.
1040
}
1041

    
1042
/**
1043
 * Implements hook_node_delete().
1044
 */
1045
function nodeaccess_node_delete($node) {
1046
  // Deleting node, delete related permissions.
1047
  db_delete('nodeaccess')
1048
  ->condition('nid', $node->nid)
1049
  ->execute();
1050
  foreach (array('uid', 'rid', 'author') as $type) {
1051
    $realm = 'nodeaccess_' . $type;
1052
    node_access_write_grants($node, array(), $realm);
1053
  }
1054
}
1055

    
1056
/**
1057
 * Implements hook_node_access_records().
1058
 */
1059
function nodeaccess_node_access_records($node) {
1060
  if (nodeaccess_disabling()) {
1061
    return;
1062
  }
1063
  // Need to find out if node has own grants or whether to use defaults.
1064
  $default = variable_get('nodeaccess_' . $node->type, array());
1065

    
1066
  // Setup default keys that are required by node_access_write_grants().
1067
  $grant_defaults = array(
1068
    'gid' => 0,
1069
    'realm' => 'nodeaccess_rid',
1070
    'grant_view' => 0,
1071
    'grant_update' => 0,
1072
    'grant_delete' => 0,
1073
    'priority' => variable_get('nodeaccess-priority', 0),
1074
  );
1075

    
1076
  $result = db_query("SELECT count(*) FROM {nodeaccess} WHERE nid = :nid", array(':nid' => $node->nid))->fetchField();
1077
  if ($result < 1) {
1078
    // Node has no own grants, use defaults if published.
1079
    if ($node->status) {
1080
      $grants = $default;
1081
    }
1082
    else {
1083
      // Otherwise, check access to unpublished content for authenticated and
1084
      // anonymous users.
1085
      $role_perms = user_role_permissions(array(
1086
        DRUPAL_ANONYMOUS_RID => DRUPAL_ANONYMOUS_RID,
1087
        DRUPAL_AUTHENTICATED_RID => DRUPAL_AUTHENTICATED_RID,
1088
      ));
1089
      // Anonymous user setting.
1090
      $grants = array();
1091
      $grants[] = array(
1092
        'gid' => DRUPAL_ANONYMOUS_RID,
1093
        'grant_view' => isset($role_perms[DRUPAL_ANONYMOUS_RID]['bypass node access']) ?
1094
          intval($role_perms[DRUPAL_ANONYMOUS_RID]['bypass node access']) : 0,
1095
      );
1096
      // Authenticated user setting.
1097
      $grants[] = array(
1098
        'gid' => DRUPAL_AUTHENTICATED_RID,
1099
        'grant_view' => isset($role_perms[DRUPAL_AUTHENTICATED_RID]['bypass node access']) ?
1100
          intval($role_perms[DRUPAL_AUTHENTICATED_RID]['bypass node access']) : 0,
1101
      );
1102
    }
1103
  }
1104
  else {
1105
    // Node has own grants, use them.
1106
    $result = db_query("SELECT nid, gid, realm, grant_view, grant_update, grant_delete FROM {nodeaccess} WHERE nid = :nid", array(':nid' => $node->nid));
1107
    $grants = array();
1108
    foreach ($result as $row) {
1109
      $grants[] = array(
1110
        'gid' => $row->gid,
1111
        'realm' => $row->realm,
1112
        'grant_view' => $row->grant_view,
1113
        'grant_update' => $row->grant_update,
1114
        'grant_delete' => $row->grant_delete,
1115
      );
1116
    }
1117
  }
1118
  // Apply author grants.
1119
  $author_prefs = variable_get('nodeaccess_authors', array());
1120
  // Array is prepopulated with grant values.
1121
  $grant = $author_prefs[$node->type];
1122
  $grant['gid'] = $node->uid;
1123
  $grant['realm'] = 'nodeaccess_author';
1124
  // Include author grant even with all values FALSE, it may be
1125
  // needed to overwrite an older value.
1126
  $grants[] = $grant;
1127

    
1128
  foreach ($grants as $id => $grant) {
1129
    // Merge missing default grant keys.
1130
    $grants[$id] = $grants[$id] + $grant_defaults;
1131
  }
1132
  return $grants;
1133
}
1134

    
1135
/**
1136
 * Mark module to be in process of disabling.
1137
 *
1138
 * Prevents entries being saved to node_access while module is being disabled.
1139
 *
1140
 * @param mixed $set
1141
 *   A boolean set or NULL to not change status.
1142
 */
1143
function nodeaccess_disabling($set = NULL) {
1144
  static $disabling = FALSE;
1145
  if ($set !== NULL) {
1146
    $disabling = $set;
1147
  }
1148
  return $disabling;
1149
}
1150

    
1151
/**
1152
 * Implements hook_node_type_delete().
1153
 */
1154
function nodeaccess_node_type_delete($info) {
1155
  // Node type is being deleted, delete its preferences.
1156
  variable_del('nodeaccess_' . $info->type);
1157
  $author_prefs = variable_get('nodeaccess_authors', array());
1158
  unset($author_prefs[$info->type]);
1159
  variable_set('nodeaccess_authors', $author_prefs);
1160
}
1161

    
1162
/**
1163
 * Implements hook_node_type_update().
1164
 */
1165
function nodeaccess_node_type_update($info) {
1166
  // Node type has changed, move preferences to new type.
1167
  if (!empty($info->old_type) && $info->old_type != $info->type) {
1168
    $setting = variable_get('nodeaccess_' . $info->old_type, array());
1169
    variable_del('nodeaccess_' . $info->old_type);
1170
    variable_set('nodeaccess_' . $info->type, $setting);
1171
    $author_prefs = variable_get('nodeaccess_authors', array());
1172
    $author_prefs[$info->type] = array(
1173
      'grant_view' => $author_prefs[$info->old_type]['grant_view'],
1174
      'grant_update' => $author_prefs[$info->old_type]['grant_update'],
1175
      'grant_delete' => $author_prefs[$info->old_type]['grant_delete'],
1176
    );
1177
    unset($author_prefs[$info->old_type]);
1178
    variable_set('nodeaccess_authors', $author_prefs);
1179
  }
1180
}
1181

    
1182
/**
1183
 * Implements hook_node_type_insert().
1184
 */
1185
function nodeaccess_node_type_insert($info) {
1186
  // New node type, default to whatever is set for access content permission.
1187
  $role_perms = user_role_permissions(array(1 => 1, 2 => 2));
1188
  $role_perms[1]['access content'] = isset($role_perms[1]['access content'])?
1189
                                      intval($role_perms[1]['access content']) : 0;
1190
  $role_perms[2]['access content'] = isset($role_perms[2]['access content'])?
1191
                                      intval($role_perms[2]['access content']) : 0;
1192
  $grants[] = array(
1193
    'gid' => 1,
1194
    'realm' => 'nodeaccess_rid',
1195
    'grant_view' => $role_perms[1]['access content'],
1196
    'grant_update' => 0,
1197
    'grant_delete' => 0,
1198
  );
1199
  $grants[] = array(
1200
    'gid' => 2,
1201
    'realm' => 'nodeaccess_rid',
1202
    'grant_view' => $role_perms[1]['access content'],
1203
    'grant_update' => 0,
1204
    'grant_delete' => 0,
1205
  );
1206
  variable_set('nodeaccess_' . $info->type, $grants);
1207
  // Add all permissions for author.
1208
  $author_prefs = variable_get('nodeaccess_authors', array());
1209
  $author_prefs[$info->type] = array(
1210
    'grant_view' => 0,
1211
    'grant_update' => 0,
1212
    'grant_delete' => 0,
1213
  );
1214
  variable_set('nodeaccess_authors', $author_prefs);
1215
  node_access_needs_rebuild(TRUE);
1216
}
1217

    
1218
/**
1219
 * Retrieve role aliases.
1220
 *
1221
 * @return array or role aliases indexed by rid.
1222
 */
1223
function nodeaccess_get_role_aliases() {
1224
  $aliases = array();
1225
  $sql = 'SELECT r.rid, r.name, a.name AS alias, a.weight
1226
    FROM {role} r
1227
    LEFT JOIN {nodeaccess_role_alias} a ON r.rid = a.rid
1228
    ORDER BY a.weight, r.weight, a.name, r.name';
1229
  $results = db_query($sql);
1230
  foreach ($results as $a) {
1231
    $aliases[$a->rid]['name'] = $a->name;
1232
    $aliases[$a->rid]['alias'] = $a->alias;
1233
    $aliases[$a->rid]['weight'] = $a->weight;
1234
  }
1235
  return $aliases;
1236
}
1237

    
1238

    
1239
/**
1240
 * Save a role alias.
1241
 *
1242
 * @param array $edit
1243
 *   An array of aliases to save, indexed by rid.
1244
 */
1245
function nodeaccess_save_role_aliases($edit) {
1246
  db_delete('nodeaccess_role_alias')->execute();
1247
  if (is_array($edit)) {
1248
    foreach ($edit as $key => $value) {
1249
      db_insert('nodeaccess_role_alias')->fields(array(
1250
        'rid' => $key,
1251
        'name' => $value['name'],
1252
        'weight' => $value['weight'],
1253
      ))->execute();
1254
    }
1255
  }
1256

    
1257
  return;
1258
}
1259

    
1260
/**
1261
 * Insert userreference grants from a node.
1262
 */
1263
function nodeaccess_insert_user_reference($node) {
1264
  $form_values = _nodeaccess_get_grants($node);
1265
  // Now, append or overwrite the uid with what was specified in the user
1266
  // reference field.
1267
  $fields = variable_get('nodeaccess_' . $node->type . '_user_reference', array());
1268
  foreach ($fields as $field_name => $field) {
1269
    $user_uids = field_get_items('node', $node, $field_name);
1270
    $user_references = user_load_multiple($user_uids);
1271
    // Add each of the referenced users a form value.
1272
    foreach ($user_references as $user) {
1273
      $form_values['uid'][$user->uid] = array(
1274
        'name' => $user->name,
1275
        'keep' => 1,
1276
        'grant_view' => $field['grant_view'],
1277
        'grant_update' => $field['grant_update'],
1278
        'grant_delete' => $field['grant_delete'],
1279
      );
1280
    }
1281
  }
1282
  // Only do the changes if there are users to save.
1283
  if (count($form_values['uid']) > 0) {
1284
    $form_values['nid'] = $node->nid;
1285
    $form_state = array('values' => $form_values);
1286
    _nodeaccess_grants_form_submit(NULL, $form_state);
1287
  }
1288
}
1289

    
1290
/**
1291
 * Delete all userreference user grants from a node.
1292
 */
1293
function nodeaccess_delete_user_reference($node) {
1294
  $form_values = _nodeaccess_get_grants($node);
1295
  // Now, append or overwrite the uid with what was specified in the user
1296
  // reference field.
1297
  $fields = variable_get('nodeaccess_' . $node->type . '_user_reference', array());
1298
  foreach ($fields as $field_name => $field) {
1299
    $user_uids = field_get_items('node', $node, $field_name);
1300
    $user_references = user_load_multiple($user_uids);
1301
    foreach ($user_references as $user) {
1302
      unset($form_values['uid'][$user->uid]);
1303
    }
1304
  }
1305
  $form_values['nid'] = $node->nid;
1306
  $form_state = array('values' => $form_values);
1307
  _nodeaccess_grants_form_submit(NULL, $form_state);
1308
}
1309

    
1310
/**
1311
 * Return the grants applied to a node object used for Grant form.
1312
 *
1313
 * @return array
1314
 *   An array of grants with keys 'rid' for roles and 'uid' for users.
1315
 */
1316
function _nodeaccess_get_grants($node) {
1317
  $grants = array();
1318
  // Load all roles.
1319
  $result = db_query("SELECT r.rid, nra.name, na.grant_view, na.grant_update, na.grant_delete FROM {role} r LEFT JOIN {nodeaccess_role_alias} nra ON r.rid = nra.rid LEFT JOIN {node_access} na ON r.rid = na.gid AND na.realm = :realm AND na.nid = :nid ORDER BY nra.weight, nra.name",
1320
    array(
1321
      ':realm' => 'nodeaccess_rid',
1322
      ':nid' => $node->nid,
1323
    ));
1324
  foreach ($result as $grant) {
1325
    $grants['rid'][$grant->rid] = array(
1326
      'name' => $grant->name,
1327
      'grant_view' => (boolean) $grant->grant_view,
1328
      'grant_update' => (boolean) $grant->grant_update,
1329
      'grant_delete' => (boolean) $grant->grant_delete,
1330
    );
1331
  }
1332
  // Load users from node_access.
1333
  $result = db_query("SELECT uid, name, grant_view, grant_update, grant_delete FROM {node_access} LEFT JOIN {users} ON uid = gid WHERE nid = :nid AND realm = :realm ORDER BY name",
1334
    array(
1335
      ':nid' => $node->nid,
1336
      ':realm' => 'nodeaccess_uid',
1337
    ));
1338
  foreach ($result as $account) {
1339
    $grants['uid'][$account->uid] = array(
1340
      'name' => $account->name,
1341
      'keep' => 1,
1342
      'grant_view' => $account->grant_view,
1343
      'grant_update' => $account->grant_update,
1344
      'grant_delete' => $account->grant_delete,
1345
    );
1346
  }
1347
  return $grants;
1348
}