Projet

Général

Profil

Paste
Télécharger (42,3 ko) Statistiques
| Branche: | Révision:

root / htmltest / sites / all / modules / nodeaccess / nodeaccess.module @ c12e7e6a

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 '<small>' . t('You can set grants per users. Enter a name or a partial name in the box and click Search or press return. You need to check the Keep? checkbox if you want to keep the user for granting. Note that user grants are additional to those coming from roles.') . '</small>';
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]) &&
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'  => 'role',
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
 * Menu callback. Draws the admin page.
180
 */
181
function nodeaccess_admin_form($form, $form_state) {
182
  // Set defaults from variable_get.
183
  $show = variable_get('nodeaccess-types', array());
184
  $roles = nodeaccess_get_role_aliases();
185
  $allowed_roles = variable_get('nodeaccess-roles', array());
186
  $allowed_grants = variable_get('nodeaccess-grants', array());
187

    
188
  $form['priority'] = array(
189
    '#type' => 'checkbox',
190
    '#title' => t('Give node grants priority'),
191
    '#default_value' => variable_get('nodeaccess-priority', 0),
192
    '#description' => '<small>' . 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.') . '</small>',
193
  );
194

    
195
  // Select whether to preserve hidden grants.
196
  $form['preserve'] = array(
197
    '#type' => 'checkbox',
198
    '#title' => t('Preserve hidden grants'),
199
    '#default_value' => variable_get('nodeaccess-preserve', 1),
200
    '#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>',
201
  );
202

    
203
  // Select permissions you want to allow users to view and edit.
204
  $form['grant'] = array(
205
    '#type' => 'fieldset',
206
    '#collapsible' => TRUE,
207
    '#collapsed' => TRUE,
208
    '#title' => t('Allowed Grants'),
209
    '#tree' => TRUE,
210
    '#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>',
211
  );
212
  $form['grant']['view'] = array(
213
    '#type' => 'checkbox',
214
    '#title' => t('View'),
215
    '#default_value' => $allowed_grants['view'],
216
  );
217
  $form['grant']['edit'] = array(
218
    '#type' => 'checkbox',
219
    '#title' => t('Edit'),
220
    '#default_value' => $allowed_grants['edit'],
221
  );
222
  $form['grant']['delete'] = array(
223
    '#type' => 'checkbox',
224
    '#title' => t('Delete'),
225
    '#default_value' => $allowed_grants['delete'],
226
  );
227

    
228
  // Select roles the permissions of which you want to allow users to
229
  // view and edit, and the aliases and weights of those roles.
230
  $form['role'] = array(
231
    '#type' => 'fieldset',
232
    '#collapsible' => TRUE,
233
    '#collapsed' => TRUE,
234
    '#title' => t('Allowed Roles'),
235
    '#tree' => TRUE,
236
    '#theme' => 'nodeaccess_admin_form_roles',
237
    '#description' => '<small>' . 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.') . '</small>',
238
  );
239

    
240
  foreach ($roles as $id => $role) {
241
    // Catch NULL values.
242
    if (!$role['alias']) {
243
      $role['alias'] = '';
244
    }
245
    if (!$role['weight']) {
246
      $role['weight'] = 0;
247
    }
248
    // $form['role'][$id] = array('#tree' => TRUE);
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
  }
401
  variable_set('nodeaccess-roles', $allowed_roles);
402
  nodeaccess_save_role_aliases($alias_prefs);
403
  // Save author and role permissions for each node type.
404
  $author_prefs = array();
405
  foreach (node_type_get_types() as $type => $name) {
406
    $grants = array();
407
    foreach ($form_values[$type]['roles'] as $role => $val) {
408
      $grants[] = array(
409
        'gid' => $role,
410
        'realm' => 'nodeaccess_rid',
411
        'grant_view' => $val['grant_view'],
412
        'grant_update' => $val['grant_update'],
413
        'grant_delete' => $val['grant_delete'],
414
      );
415
    }
416
    variable_set('nodeaccess_' . $type, $grants);
417
    if ($form_values[$type]['show']) {
418
      $allowed_types[$type] = 1;
419
    }
420
    else {
421
      $allowed_types[$type] = 0;
422
    }
423
    $author_prefs[$type] = $form_values[$type]['author'];
424
    // Also save userreference default permissions if enabled.
425
    if (module_exists('user_reference') && isset($form_values[$type]['user_reference'])) {
426
      $user_reference_grants = array();
427
      foreach ($form_values[$type]['user_reference'] as $user_reference_field => $val) {
428
        $user_reference_grants[$user_reference_field] = array(
429
          'gid' => 'nodeaccess_uid',
430
          'enabled' => $val['enabled'],
431
          'grant_view' => $val['grant_view'],
432
          'grant_update' => $val['grant_update'],
433
          'grant_delete' => $val['grant_delete'],
434
        );
435
      }
436
      variable_set('nodeaccess_' . $type . '_user_reference', $user_reference_grants);
437
    }
438
  }
439
  variable_set('nodeaccess_authors', $author_prefs);
440
  // Save allowed node types.
441
  variable_set('nodeaccess-types', $allowed_types);
442
  node_access_needs_rebuild(TRUE);
443
  drupal_set_message(t('Grants saved.'));
444
}
445

    
446
/**
447
 * Theme functions for nodeaccess_admin_form.
448
 */
449
function theme_nodeaccess_admin_form_roles($variables) {
450
  $output = '';
451
  $roles = $variables['role'];
452
  $header = array(t('Allow Role'), t('Alias'), t('Weight'));
453

    
454
  foreach ($roles as $role) {
455
    if (!is_array($role) || !isset($role['allow'])) {
456
      continue;
457
    }
458
    $row = array();
459
    $row[] = drupal_render($role['allow']);
460
    $row[] = drupal_render($role['alias']);
461
    $row[] = drupal_render_children($role['weight']);
462
    $rows[] = $row;
463
  }
464
  $output .= theme('table', array('header' => $header, 'rows' => $rows));
465

    
466
  return $output;
467
}
468

    
469
/**
470
 * Output the grant table.
471
 * @todo Please document this function.
472
 * @see http://drupal.org/node/1354
473
 */
474
function theme_nodeaccess_admin_form_types($variables) {
475
  // @todo Number of parameters does not match hook_theme.
476
  $form = $variables['form'];
477
  $output = drupal_render($form['show']);
478
  $roles = element_children($form['roles']);
479
  $header = array(t('Role'), t('View'), t('Edit'), t('Delete'));
480
  foreach ($roles as $role) {
481
    $row = array();
482
    $row[] = drupal_render($form['roles'][$role]['name']);
483
    $row[] = drupal_render($form['roles'][$role]['grant_view']);
484
    $row[] = drupal_render($form['roles'][$role]['grant_update']);
485
    $row[] = drupal_render($form['roles'][$role]['grant_delete']);
486
    $rows[] = $row;
487
  }
488
  $output .= theme('table', array('header' => $header, 'rows' => $rows));
489
  $header = array(t('Author Settings'), t('View'), t('Edit'), t('Delete'));
490
  $row = array();
491
  $row[] = t('Node author');
492
  $row[] = drupal_render($form['author']['grant_view']);
493
  $row[] = drupal_render($form['author']['grant_update']);
494
  $row[] = drupal_render($form['author']['grant_delete']);
495

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

    
498
  $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>';
499

    
500
  if (module_exists('user_reference') && isset($form['user_reference'])) {
501
    $user_reference_fields = element_children($form['user_reference']);
502
    $header = array(t('User Reference Field'),
503
      t('Enable this field'),
504
      t('View'),
505
      t('Edit'),
506
      t('Delete'),
507
    );
508
    $rows = array();
509
    foreach ($user_reference_fields as $user_reference_field) {
510
      $row = array();
511

    
512
      $row[] = $form['user_reference'][$user_reference_field]['name']['#value'];
513
      $row[] = drupal_render($form['user_reference'][$user_reference_field]['enabled']);
514
      $row[] = drupal_render($form['user_reference'][$user_reference_field]['grant_view']);
515
      $row[] = drupal_render($form['user_reference'][$user_reference_field]['grant_update']);
516
      $row[] = drupal_render_children($form['user_reference'][$user_reference_field]['grant_delete']);
517
      $rows[] = $row;
518
    }
519
    $output .= theme('table', array(
520
        'header' => $header,
521
        'rows' => $rows,
522
      ));
523
    $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>';
524
  }
525
  return $output;
526
}
527

    
528
/**
529
 * Menu callback. Draws the grant tab.
530
 */
531
function nodeaccess_grants($node) {
532
  return drupal_get_form('nodeaccess_grants_form', $node);
533
}
534

    
535
/**
536
 * Menu callback. Draws the grant tab.
537
 */
538
function nodeaccess_grants_form($form, &$form_state, $node) {
539
  $form_values = &$form_state['values'];
540
  if (!$form_values) {
541
    $form_values = array();
542
    // Load all roles.
543
    $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", array(':realm' => 'nodeaccess_rid', ':nid' => $node->nid));
544
    foreach ($result as $grant) {
545
      $form_values['rid'][$grant->rid] = array(
546
        'name' => $grant->name,
547
        'grant_view' => (boolean) $grant->grant_view,
548
        'grant_update' => (boolean) $grant->grant_update,
549
        'grant_delete' => (boolean) $grant->grant_delete,
550
      );
551
    }
552
    // Load users from node_access.
553
    $results = 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", array(
554
        ':nid' => $node->nid,
555
        ':realm' => 'nodeaccess_uid',
556
      ));
557
    foreach ($results as $account) {
558
      $form_values['uid'][$account->uid] = array(
559
        'name' => $account->name,
560
        'keep' => 1,
561
        'grant_view' => $account->grant_view,
562
        'grant_update' => $account->grant_update,
563
        'grant_delete' => $account->grant_delete,
564
      );
565
    }
566
  }
567
  else {
568
    // Perform search.
569
    if ($form_values['keys']) {
570
      // @todo rewrite
571
      $params = array();
572
      $sql = "SELECT uid, name FROM {users} WHERE name LIKE :name";
573
      $name = preg_replace('!\*+!', '%', $form_values['keys']);
574
      $params[':name'] = $name;
575
      $users = '';
576
      if (isset($form_values['uid']) && is_array($form_values['uid'])) {
577
        $sql .= ' AND uid NOT IN (:uid)';
578
        $users = implode(',', array_keys($form_values['uid']));
579
        $params[':uid'] = $users;
580
      }
581

    
582
      $result = db_query($sql, $params);
583
      foreach ($result as $account) {
584

    
585
        $form_values['uid'][$account->uid] = array(
586
          'name' => $account->name,
587
          'keep' => 0,
588
        );
589
      }
590
    }
591
    // Calculate default grants for found users.
592
    // rewrite
593
    if (isset($form_values['uid']) && is_array($form_values['uid'])) {
594
      foreach (array_keys($form_values['uid']) as $uid) {
595
        if (!$form_values['uid'][$uid]['keep']) {
596
          foreach (array('grant_view', 'grant_update', 'grant_delete') as $grant_type) {
597
            $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 :type = 1",
598
              0, 1,
599
              array(
600
                ':nid' => $node->nid,
601
                ':realm' => 'nodeaccess_rid',
602
                ':uid' => $uid,
603
                ':type' => $grant_type,
604
              ))->fetchField() ||
605
              db_query_range("SELECT count(*) FROM {node_access} na WHERE nid = :nid AND realm = :realm AND gid = :gid AND :type = 1",
606
                0, 1,
607
                array(
608
                  ':nid' => $node->nid,
609
                  ':realm' => 'nodeaccess_uid',
610
                  ':gid' => $uid,
611
                  ':type' => $grant_type,
612
                )
613
                )->fetchField();
614
          }
615
          $form_values['uid'][$uid]['keep'] = TRUE;
616
        }
617
      }
618
    }
619
  }
620
  if (!isset($form_values['rid'])) {
621
    $form_values['rid'] = array();
622
  }
623

    
624
  if (!isset($form_values['uid'])) {
625
    $form_values['uid'] = array();
626
  }
627

    
628
  $roles = $form_values['rid'];
629
  $users = $form_values['uid'];
630

    
631
  $form['nid'] = array(
632
    '#type' => 'hidden',
633
    '#value' => $node->nid,
634
  );
635

    
636
  $allowed_roles = variable_get('nodeaccess-roles', array());
637
  $allowed_grants = variable_get('nodeaccess-grants', array());
638
  // If $preserve is TRUE, the fields the user is not allowed to view or
639
  // edit are included in the form as hidden fields to preserve them.
640
  $preserve = variable_get('nodeaccess-preserve', 1);
641

    
642
  // Roles table.
643
  if (is_array($roles)) {
644
    $form['rid'] = array('#tree' => TRUE);
645
    foreach ($roles as $key => $field) {
646
      if (isset($allowed_roles[$key]) && $allowed_roles[$key]) {
647
          $form['rid'][$key]['name'] = array(
648
            '#type' => 'hidden',
649
            '#value' => $field['name'],
650
          );
651
          if ($allowed_grants['view']) {
652
            $form['rid'][$key]['grant_view'] = array(
653
              '#type' => 'checkbox',
654
              '#default_value' => $field['grant_view'],
655
            );
656
          }
657
          elseif ($preserve) {
658
            $form['rid'][$key]['grant_view'] = array(
659
              '#type' => 'hidden',
660
              '#value' => $field['grant_view'],
661
            );
662
          }
663
          if ($allowed_grants['edit']) {
664
            $form['rid'][$key]['grant_update'] = array(
665
              '#type' => 'checkbox',
666
              '#default_value' => $field['grant_update'],
667
            );
668
          }
669
          elseif ($preserve) {
670
            $form['rid'][$key]['grant_update'] = array(
671
              '#type' => 'hidden',
672
              '#value' => $field['grant_update'],
673
            );
674
          }
675
          if ($allowed_grants['delete']) {
676
            $form['rid'][$key]['grant_delete'] = array(
677
              '#type' => 'checkbox',
678
              '#default_value' => $field['grant_delete'],
679
            );
680
          }
681
          elseif ($preserve) {
682
            $form['rid'][$key]['grant_delete'] = array(
683
              '#type' => 'hidden',
684
              '#value' => $field['grant_delete'],
685
            );
686
          }
687
      }
688
      elseif ($preserve) {
689
        $form['rid'][$key]['name'] = array(
690
          '#type' => 'hidden',
691
          '#value' => $field['name'],
692
        );
693
        $form['rid'][$key]['grant_view'] = array(
694
          '#type' => 'hidden',
695
          '#value' => $field['grant_view'],
696
        );
697
        $form['rid'][$key]['grant_update'] = array(
698
          '#type' => 'hidden',
699
          '#value' => $field['grant_update'],
700
        );
701
        $form['rid'][$key]['grant_delete'] = array(
702
          '#type' => 'hidden',
703
          '#value' => $field['grant_delete'],
704
        );
705
      }
706
    }
707
  }
708

    
709
  // Users table.
710
  if (is_array($users)) {
711
    $form['uid'] = array('#tree' => TRUE);
712
    foreach ($users as $key => $field) {
713
      $form['uid'][$key]['name'] = array(
714
        '#type' => 'hidden',
715
        '#value' => $field['name'],
716
      );
717
      $form['uid'][$key]['keep'] = array(
718
        '#type' => 'checkbox',
719
        '#default_value' => $field['keep'],
720
      );
721
      if ($allowed_grants['view']) {
722
        $form['uid'][$key]['grant_view'] = array(
723
          '#type' => 'checkbox',
724
          '#default_value' => $field['grant_view'],
725
        );
726
      }
727
      elseif ($preserve) {
728
        $form['uid'][$key]['grant_view'] = array(
729
          '#type' => 'hidden',
730
          '#value' => $field['grant_view'],
731
        );
732
      }
733
      if ($allowed_grants['edit']) {
734
        $form['uid'][$key]['grant_update'] = array(
735
          '#type' => 'checkbox',
736
          '#default_value' => $field['grant_update'],
737
        );
738
      }
739
      elseif ($preserve) {
740
        $form['uid'][$key]['grant_update'] = array(
741
          '#type' => 'hidden',
742
          '#value' => $field['grant_update'],
743
        );
744
      }
745
      if ($allowed_grants['delete']) {
746
        $form['uid'][$key]['grant_delete'] = array(
747
          '#type' => 'checkbox',
748
          '#default_value' => $field['grant_delete'],
749
        );
750
      }
751
      elseif ($preserve) {
752
        $form['uid'][$key]['grant_delete'] = array(
753
          '#type' => 'hidden',
754
          '#value' => $field['grant_delete'],
755
        );
756
      }
757
    }
758
  }
759

    
760
  // Autocomplete returns errors if users don't have access to profiles.
761
  if (user_access('access user profiles')) {
762
    $form['keys'] = array(
763
      '#type' => 'textfield',
764
      '#default_value' => isset($form_values['keys']) ? $form_values['keys'] : '',
765
      '#size' => 40,
766
      '#autocomplete_path' => 'user/autocomplete',
767
    );
768
  }
769
  else {
770
    $form['keys'] = array(
771
      '#type' => 'textfield',
772
      '#default_value' => isset($form_values['keys'])? $form_values['keys'] : '',
773
      '#size' => 40,
774
    );
775
  }
776

    
777
  $form['search'] = array(
778
    '#type' => 'submit',
779
    '#value' => t('Search'),
780
  );
781

    
782
  $form['submit'] = array(
783
    '#type' => 'submit',
784
    '#value' => t('Save Grants'),
785
  );
786
  return $form;
787
}
788

    
789
/**
790
 * Validate function for nodeaccess_grants_form.
791
 */
792
function nodeaccess_grants_form_validate($form, $form_state) {
793
  $form_values = &$form_state['values'];
794
  // Delete unkept users.
795
  if (isset($form_values['uid']) && is_array($form_values['uid'])) {
796
    foreach ($form_values['uid'] as $uid => $row) {
797
      if (!$row['keep']) {
798
        unset($form_values['uid'][$uid]);
799
      }
800
    }
801
  }
802
  if (!isset($form_values['uid'])) {
803
    unset($form_values['uid']);
804
  }
805

    
806
}
807

    
808
/**
809
 * Submit function for nodeaccess_grants_form.
810
 */
811
function nodeaccess_grants_form_submit($form, &$form_state) {
812

    
813
  if ($form_state['clicked_button']['#id'] == 'edit-search') {
814
    $form_state['rebuild'] = TRUE;
815
    $form_state['storage']['values'] = $form_state['values'];
816
  }
817
  else {
818
    unset($form_state['rebuild']);
819
    _nodeaccess_grants_form_submit($form, $form_state);
820
    drupal_set_message(t('Grants saved.'));
821
  }
822
}
823

    
824
/**
825
 * Private function to submit the per-node grants table.
826
 */
827
function _nodeaccess_grants_form_submit($form, $form_state) {
828
  $form_values = &$form_state['values'];
829
  global $user;
830
  $grants = array();
831
  $nid = $form_values['nid'];
832
  $node = node_load($nid);
833
  foreach (array('uid', 'rid') as $type) {
834
    $realm = 'nodeaccess_' . $type;
835
    if (isset($form_values[$type]) && is_array($form_values[$type])) {
836
      foreach ($form_values[$type] as $gid => $line) {
837
        $grant = array(
838
          'gid' => $gid,
839
          'realm' => $realm,
840
          'grant_view' => empty($line['grant_view']) ? 0 : $line['grant_view'],
841
          'grant_update' => empty($line['grant_update']) ? 0 : $line['grant_update'],
842
          'grant_delete' => empty($line['grant_delete']) ? 0 : $line['grant_delete'],
843
        );
844
        if ($grant['grant_view'] || $grant['grant_update'] || $grant['grant_delete']) {
845
          $grants[] = $grant;
846
        }
847
      }
848
    }
849
    node_access_write_grants($node, $grants, $realm);
850
  }
851

    
852
  // Save role and user grants to our own table.
853
  db_delete('nodeaccess')
854
  ->condition('nid', $nid)
855
  ->execute();
856
  foreach ($grants as $grant) {
857
    $id = db_insert('nodeaccess')
858
        ->fields(array(
859
          'nid' => $nid,
860
          'gid' => $grant['gid'],
861
          'realm' => $grant['realm'],
862
          'grant_view' => $grant['grant_view'],
863
          'grant_update' => $grant['grant_update'],
864
          'grant_delete' => $grant['grant_delete'],
865
        ))
866
    ->execute();
867
  }
868
}
869

    
870
/**
871
 * Theme function for nodeaccess_grants_form.
872
 */
873
function theme_nodeaccess_grants_form($variables) {
874
  $output = '';
875
  // @todo: Number of parameters in this theme function does not match number
876
  // of parameters found in hook_theme.
877
  $form = $variables['form'];
878
  $rows = array();
879
  $allowed_roles = variable_get('nodeaccess-roles', array());
880
  $allowed_grants = variable_get('nodeaccess-grants', array());
881
  // Retrieve role names for columns.
882
  $role_names = user_roles();
883
  // Roles table.
884
  $roles = element_children($form['rid']);
885

    
886
  if (count($roles) && count($allowed_roles)) {
887
    $header = array();
888
    $header[] = t('Role');
889
    if ($allowed_grants['view']) {
890
      $header[] = t('View');
891
    }
892
    if ($allowed_grants['edit']) {
893
      $header[] = t('Edit');
894
    }
895
    if ($allowed_grants['delete']) {
896
      $header[] = t('Delete');
897
    }
898
    foreach ($roles as $key) {
899
      if (isset($allowed_roles[$key]) && $allowed_roles[$key]) {
900
        $row = array();
901
        $row[] = $role_names[$key] . drupal_render($form['rid'][$key]['name']);
902
        if ($allowed_grants['view']) {
903
          $row[] = drupal_render($form['rid'][$key]['grant_view']);
904
        }
905
        if ($allowed_grants['edit']) {
906
          $row[] = drupal_render($form['rid'][$key]['grant_update']);
907
        }
908
        if ($allowed_grants['delete']) {
909
          $row[] = drupal_render($form['rid'][$key]['grant_delete']);
910
        }
911
        $rows[] = $row;
912
      }
913
    }
914
    $output .= theme('table', array('header' => $header, 'rows' => $rows));
915
  }
916

    
917
  // Search form.
918
  $output .= '<p><div class="search-form">';
919
  $output .= '<strong>' . t('Enter names to search for users:') . '</strong>';
920
  $output .= '<div class="container-inline">';
921
  $output .= drupal_render($form['keys']);
922
  $output .= drupal_render($form['search']);
923
  $output .= '</div></div></p>';
924

    
925
  // Users table.
926
  unset($rows);
927
  $users = element_children($form['uid']);
928
  if (count($users) > 0) {
929
    $header = array();
930
    $rows = array();
931
    $header[] = t('User');
932
    $header[] = t('Keep?');
933
    if ($allowed_grants['view']) {
934
      $header[] = t('View');
935
    }
936
    if ($allowed_grants['edit']) {
937
      $header[] = t('Edit');
938
    }
939
    if ($allowed_grants['delete']) {
940
      $header[] = t('Delete');
941
    }
942
    foreach ($users as $key) {
943
      $row = array();
944
      $row[] = $form['uid'][$key]['name']['#value'];
945
      $row[] = drupal_render($form['uid'][$key]['keep']);
946
      if ($allowed_grants['view']) {
947
        $row[] = drupal_render($form['uid'][$key]['grant_view']);
948
      }
949
      if ($allowed_grants['edit']) {
950
        $row[] = drupal_render($form['uid'][$key]['grant_update']);
951
      }
952
      if ($allowed_grants['delete']) {
953
        $row[] = drupal_render($form['uid'][$key]['grant_delete']);
954
      }
955
      $rows[] = $row;
956
    }
957
    $output .= theme('table', array('header' => $header, 'rows' => $rows));
958
  }
959

    
960
  $output .= drupal_render_children($form);
961

    
962
  return $output;
963
}
964

    
965
/**
966
 * Implements hook_node_grants().
967
 */
968
function nodeaccess_node_grants($account, $op) {
969
  $roles = is_array($account->roles) ? array_keys($account->roles) : array(-1);
970
  return array(
971
    'nodeaccess_rid' => $roles,
972
    'nodeaccess_uid' => array($account->uid),
973
    'nodeaccess_author' => array($account->uid),
974
  );
975
}
976

    
977
/**
978
 * Implements hook_node_update().
979
 */
980
function nodeaccess_node_update($node) {
981
  // Node author may have changed, overwrite old record.
982
  $author_prefs = variable_get('nodeaccess_authors', array());
983
  // Array is prepopulated with grant values.
984
  $grant = $author_prefs[$node->type];
985
  $grant['gid'] = $node->uid;
986
  $grant['realm'] = 'nodeaccess_author';
987
  $grants = array();
988
  $grants[] = $grant;
989
  node_access_write_grants($node, $grants, 'nodeaccess_author');
990
  if (module_exists('user_reference')) {
991
    $fields = variable_get('nodeaccess_' . $node->type . '_user_reference', array());
992
    foreach (array_keys($fields) as $field_name) {
993
      if (isset($node->$field_name)) {
994
        $old_node = node_load($node->nid);
995
        // Delete the old user as it's changed.
996
        if ($node->$field_name != $old_node->$field_name) {
997
          nodeaccess_delete_user_reference($old_node);
998
          nodeaccess_insert_user_reference($node);
999
        }
1000
        break;
1001
      }
1002
    }
1003
  }
1004
  // Done, author permissions are not written into nodeaccess.
1005
}
1006

    
1007
/**
1008
 * Implements hook_node_delete().
1009
 */
1010
function nodeaccess_node_delete($node) {
1011
  // Deleting node, delete related permissions.
1012
  db_delete('nodeaccess')
1013
  ->condition('nid', $node->nid)
1014
  ->execute();
1015
  foreach (array('uid', 'rid', 'author') as $type) {
1016
    $realm = 'nodeaccess_' . $type;
1017
    node_access_write_grants($node, array(), $realm);
1018
  }
1019
}
1020
/**
1021
 * Implements hook_node_access_records().
1022
 */
1023
function nodeaccess_node_access_records($node) {
1024
  if (nodeaccess_disabling()) {
1025
    return;
1026
  }
1027
  // Need to find out if node has own grants or whether to use defaults.
1028
  $default = variable_get('nodeaccess_' . $node->type, array());
1029
  // Load priority setting.
1030
  $priority = variable_get('nodeaccess-priority', 0);
1031
  $result = db_query("SELECT count(*) FROM {nodeaccess} WHERE nid = :nid", array(':nid' => $node->nid))->fetchField();
1032
  if ($result < 1) {
1033
    // Node has no own grants, use defaults.
1034
    $grants = $default;
1035
    foreach ($grants as $id => $grant) {
1036
      $grants[$id]['priority'] = $priority;
1037
    }
1038
  }
1039
  else {
1040
    // Node has own grants, use them.
1041
    $result = db_query("SELECT nid, gid, realm, grant_view, grant_update, grant_delete FROM {nodeaccess} WHERE nid = :nid", array(':nid' => $node->nid));
1042
    $grants = array();
1043
    foreach ($result as $row) {
1044
      $grants[] = array(
1045
        'gid' => $row->gid,
1046
        'realm' => $row->realm,
1047
        'grant_view' => $row->grant_view,
1048
        'grant_update' => $row->grant_update,
1049
        'grant_delete' => $row->grant_delete,
1050
        'priority' => $priority,
1051
      );
1052
    }
1053
  }
1054
  // Apply author grants.
1055
  $author_prefs = variable_get('nodeaccess_authors', array());
1056
  // Array is prepopulated with grant values.
1057
  $grant = $author_prefs[$node->type];
1058
  $grant['gid'] = $node->uid;
1059
  $grant['realm'] = 'nodeaccess_author';
1060
  $grant['priority'] = $priority;
1061
  // Include author grant even with all values FALSE, it may be
1062
  // needed to overwrite an older value.
1063
  $grants[] = $grant;
1064
  return $grants;
1065
}
1066

    
1067
/**
1068
 * @todo Please document this function.
1069
 * @see http://drupal.org/node/1354
1070
 */
1071
function nodeaccess_disabling($set = NULL) {
1072
  static $disabling = FALSE;
1073
  if ($set !== NULL) {
1074
    $disabling = $set;
1075
  }
1076
  return $disabling;
1077
}
1078

    
1079
/**
1080
 * Implements hook_node_type_delete().
1081
 */
1082
function nodeaccess_node_type_delete($info) {
1083
  // Node type is being deleted, delete its preferences.
1084
  variable_del('nodeaccess_' . $info->type);
1085
  $author_prefs = variable_get('nodeaccess_authors', array());
1086
  unset($author_prefs[$info->type]);
1087
  variable_set('nodeaccess_authors', $author_prefs);
1088
}
1089

    
1090
/**
1091
 * Implements hook_node_type_update().
1092
 */
1093
function nodeaccess_node_type_update($info) {
1094
  // Node type has changed, move preferences to new type.
1095
  if (!empty($info->old_type) && $info->old_type != $info->type) {
1096
    $setting = variable_get('nodeaccess_' . $info->old_type, array());
1097
    variable_del('nodeaccess_' . $info->old_type);
1098
    variable_set('nodeaccess_' . $info->type, $setting);
1099
    $author_prefs = variable_get('nodeaccess_authors', array());
1100
    $author_prefs[$info->type] = array(
1101
      'grant_view' => $author_prefs[$info->old_type]['grant_view'],
1102
      'grant_update' => $author_prefs[$info->old_type]['grant_update'],
1103
      'grant_delete' => $author_prefs[$info->old_type]['grant_delete'],
1104
    );
1105
    unset($author_prefs[$info->old_type]);
1106
    variable_set('nodeaccess_authors', $author_prefs);
1107
  }
1108
}
1109

    
1110
/**
1111
 * Implements hook_node_type_insert().
1112
 */
1113
function nodeaccess_node_type_insert($info) {
1114
  // New node type, default to whatever is set for access content permission.
1115
  $role_perms = user_role_permissions(array(1 => 1, 2 => 2));
1116
  $role_perms[1]['access content'] = isset($role_perms[1]['access content'])?
1117
                                      intval($role_perms[1]['access content']) : 0;
1118
  $role_perms[2]['access content'] = isset($role_perms[2]['access content'])?
1119
                                      intval($role_perms[2]['access content']) : 0;
1120
  $grants[] = array(
1121
    'gid' => 1,
1122
    'realm' => 'nodeaccess_rid',
1123
    'grant_view' => $role_perms[1]['access content'],
1124
    'grant_update' => 0,
1125
    'grant_delete' => 0,
1126
  );
1127
  $grants[] = array(
1128
    'gid' => 2,
1129
    'realm' => 'nodeaccess_rid',
1130
    'grant_view' => $role_perms[1]['access content'],
1131
    'grant_update' => 0,
1132
    'grant_delete' => 0,
1133
  );
1134
  variable_set('nodeaccess_' . $info->type, $grants);
1135
  // Add all permissions for author.
1136
  $author_prefs = variable_get('nodeaccess_authors', array());
1137
  $author_prefs[$info->type] = array(
1138
    'grant_view' => 1,
1139
    'grant_update' => 1,
1140
    'grant_delete' => 1,
1141
  );
1142
  variable_set('nodeaccess_authors', $author_prefs);
1143
  node_access_needs_rebuild(TRUE);
1144
}
1145

    
1146
/**
1147
 * @todo Please document this function.
1148
 * @see http://drupal.org/node/1354
1149
 */
1150
function nodeaccess_get_role_aliases() {
1151
  $aliases = array();
1152
  $results = db_query('SELECT r.rid, r.name, a.name AS alias, a.weight FROM {role} r LEFT JOIN {nodeaccess_role_alias} a ON r.rid = a.rid ORDER BY r.name');
1153
  foreach ($results as $a) {
1154
    $aliases[$a->rid]['name'] = $a->name;
1155
    $aliases[$a->rid]['alias'] = $a->alias;
1156
    $aliases[$a->rid]['weight'] = $a->weight;
1157
  }
1158
  return $aliases;
1159
}
1160

    
1161
/**
1162
 * @todo Please document this function.
1163
 * @see http://drupal.org/node/1354
1164
 */
1165
function nodeaccess_save_role_aliases($edit) {
1166
  db_delete('nodeaccess_role_alias')->execute();
1167
  if (is_array($edit)) {
1168
    foreach ($edit as $key => $value) {
1169
      db_insert('nodeaccess_role_alias')->fields(array(
1170
        'rid' => $key,
1171
        'name' => $value['name'],
1172
        'weight' => $value['weight'],
1173
      ))->execute();
1174
    }
1175
  }
1176

    
1177
  return;
1178
}
1179

    
1180
/**
1181
 * Insert userreference grants from a node.
1182
 */
1183
function nodeaccess_insert_user_reference($node) {
1184
  $form_values = _nodeaccess_get_grants($node);
1185
  // Now, append or overwrite the uid with what was specified in the user
1186
  // reference field.
1187
  $fields = variable_get('nodeaccess_' . $node->type . '_user_reference', array());
1188
  foreach ($fields as $field_name => $field) {
1189
    $user_uids = field_get_items('node', $node, $field_name);
1190
    $user_references = user_load_multiple($user_uids);
1191
    // Add each of the referenced users a form value.
1192
    foreach ($user_references as $user) {
1193
      $form_values['uid'][$user->uid] = array(
1194
        'name' => $user->name,
1195
        'keep' => 1,
1196
        'grant_view' => $field['grant_view'],
1197
        'grant_update' => $field['grant_update'],
1198
        'grant_delete' => $field['grant_delete'],
1199
      );
1200
    }
1201
  }
1202
  // Only do the changes if there are users to save.
1203
  if (count($form_values['uid']) > 0) {
1204
    $form_values['nid'] = $node->nid;
1205
    $form_state = array('values' => $form_values);
1206
    _nodeaccess_grants_form_submit(NULL, $form_state);
1207
  }
1208
}
1209

    
1210
/**
1211
 * Delete all userreference user grants from a node.
1212
 */
1213
function nodeaccess_delete_user_reference($node) {
1214
  $form_values = _nodeaccess_get_grants($node);
1215
  // Now, append or overwrite the uid with what was specified in the user
1216
  // reference field.
1217
  $fields = variable_get('nodeaccess_' . $node->type . '_user_reference', array());
1218
  foreach ($fields as $field_name => $field) {
1219
    $user_uids = field_get_items('node', $node, $field_name);
1220
    $user_references = user_load_multiple($user_uids);
1221
    foreach ($user_references as $user) {
1222
      unset($form_values['uid'][$user->uid]);
1223
    }
1224
  }
1225
  $form_values['nid'] = $node->nid;
1226
  $form_state = array('values' => $form_values);
1227
  _nodeaccess_grants_form_submit(NULL, $form_state);
1228
}
1229

    
1230
/**
1231
 * Return the grants applied to a node object used for Grant form.
1232
 *
1233
 * @return array
1234
 *   An array of grants with keys 'rid' for roles and 'uid' for users.
1235
 */
1236
function _nodeaccess_get_grants($node) {
1237
  $grants = array();
1238
  // Load all roles.
1239
  $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",
1240
    array(
1241
      ':realm' => 'nodeaccess_rid',
1242
      ':nid' => $node->nid,
1243
    ));
1244
  foreach ($result as $grant) {
1245
    $grants['rid'][$grant->rid] = array(
1246
      'name' => $grant->name,
1247
      'grant_view' => (boolean) $grant->grant_view,
1248
      'grant_update' => (boolean) $grant->grant_update,
1249
      'grant_delete' => (boolean) $grant->grant_delete,
1250
    );
1251
  }
1252
  // Load users from node_access.
1253
  $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",
1254
    array(
1255
      ':nid' => $node->nid,
1256
      ':realm' => 'nodeaccess_uid',
1257
    ));
1258
  foreach ($result as $account) {
1259
    $grants['uid'][$account->uid] = array(
1260
      'name' => $account->name,
1261
      'keep' => 1,
1262
      'grant_view' => $account->grant_view,
1263
      'grant_update' => $account->grant_update,
1264
      'grant_delete' => $account->grant_delete,
1265
    );
1266
  }
1267
  return $grants;
1268
}