Projet

Général

Profil

Paste
Télécharger (30,1 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / nodeaccess / nodeaccess.module @ c2ac6d1d

1
<?php
2

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

    
8

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

    
27

    
28
/**
29
 * Implements hook_menu().
30
 *
31
 * @return array
32
 */
33
function nodeaccess_menu() {
34
  $items = array();
35

    
36
  $items['admin/config/people/nodeaccess'] = array(
37
    'title' => 'Nodeaccess',
38
    'description' => 'Change default settings for the Nodeaccess module.',
39
    'page callback' => 'nodeaccess_admin',
40
    'file' => 'nodeaccess.admin.inc',
41
    'access arguments' => array('administer nodeaccess'),
42
  );
43

    
44
  $items['node/%node/grant'] = array(
45
    'title' => 'Grant',
46
    'page callback' => 'nodeaccess_grant_tab',
47
    'page arguments' => array(1),
48
    'access callback' => 'nodeaccess_access',
49
    'access arguments' => array('grant', 1),
50
    'weight' => 5,
51
    'type' => MENU_LOCAL_TASK,
52
  );
53

    
54
  return $items;
55
}
56

    
57

    
58
/**
59
 * Implements hook_admin_paths().
60
 *
61
 * @return array
62
 */
63
function nodeaccess_admin_paths() {
64
  $paths = array(
65
    'node/*/grant' => TRUE,
66
    'admin/config/people/nodeaccess' => TRUE,
67
  );
68

    
69
  return $paths;
70
}
71

    
72
/**
73
 * Implements hook_permission().
74
 *
75
 * @return array
76
 */
77
function nodeaccess_permission() {
78

    
79
  return array(
80
    'administer nodeaccess' => array(
81
      'title' => t('Administer Nodeaccess'),
82
    ),
83
    'grant node permissions' => array(
84
      'title' => t('Grant Node Permissions'),
85
    ),
86
    'grant editable node permissions' => array(
87
      'title' => t('Grant node edit permissions'),
88
    ),
89
    'grant deletable node permissions' => array(
90
      'title' => t('Grant node delete permissions'),
91
    ),
92
    'grant own node permissions' => array(
93
      'title' => t('Grant own node permissions'),
94
    ),
95
  );
96
}
97

    
98

    
99
/**
100
 * Implements hook_node_access().
101
 *
102
 * @param $node
103
 * @param $op
104
 * @param $account
105
 *
106
 * @return string
107
 */
108
function nodeaccess_node_access($node, $op, $account) {
109

    
110
  switch ($op) {
111
    case 'update':
112
    case 'delete':
113
      if (!isset($account->uid)) {
114
        global $user;
115
        $account = $user;
116
      }
117
      // If the node belongs to a deleted user.
118
      if ($account->uid == 0 && $node->uid == 0) {
119
        $grants = nodeaccess_get_grants($node);
120
        // We check if the role has particular access to this node.
121
        // If anonymous has rights to this node, we allow them.
122
        if ((!empty($grants['rid'][DRUPAL_ANONYMOUS_RID]['grant_update']) && $op == 'update') ||
123
            (!empty($grants['rid'][DRUPAL_ANONYMOUS_RID]['grant_delete']) && $op == 'delete')) {
124
          return NODE_ACCESS_ALLOW;
125
        }
126
        return NODE_ACCESS_DENY;
127
      }
128
      break;
129
  }
130
}
131

    
132
/**
133
 * Determine access to Grant tab.
134
 *
135
 * @param $op
136
 * @param $node
137
 * @param $account
138
 *
139
 * @return bool
140
 *   Whether the user has access to the grant tab.
141
 */
142
function nodeaccess_access($op, $node, $account = NULL) {
143
  global $user;
144
  if (!$node) {
145

    
146
    return FALSE;
147
  }
148

    
149
  // Apparently D7 no longer defaults to admin getting anything?
150
  if (user_access('administer nodeaccess')) {
151

    
152
    return TRUE;
153
  }
154

    
155
  // If no user object is supplied, the access check is for the current user.
156
  if (empty($account)) {
157
    $account = $user;
158
  }
159
  $allowed_types = variable_get('nodeaccess-types', array());
160
  if ($op == 'grant') {
161
    if ($node->nid && isset($allowed_types[$node->type]) && !empty($allowed_types[$node->type]) &&
162
      (user_access('grant node permissions', $account) ||
163
      (user_access('grant editable node permissions', $account) && node_access('update', $node, $account)) ||
164
      (user_access('grant deletable node permissions', $account) && node_access('delete', $node, $account)) ||
165
      (user_access('grant own node permissions', $account) && ($account->uid == $node->uid)))) {
166

    
167
      return TRUE;
168
    }
169
  }
170

    
171
  return FALSE;
172
}
173

    
174

    
175
/**
176
 * Implements hook_theme().
177
 *
178
 * @param $existing
179
 * @param $type
180
 * @param $theme
181
 * @param $path
182
 *
183
 * @return array
184
 */
185
function nodeaccess_theme($existing, $type, $theme, $path) {
186

    
187
  return array(
188
    'nodeaccess_admin_form_roles' => array(
189
      'render element'  => 'form',
190
    ),
191
    'nodeaccess_admin_form_types' => array(
192
      'render element'  => 'form',
193
    ),
194
    'nodeaccess_grants_form'  => array(
195
      'render element'  => 'form',
196
    ),
197
  );
198
}
199

    
200

    
201
/**
202
 * Menu callback. Draws the grant tab.
203
 *
204
 * @param Object $node
205
 *
206
 * @return array
207
 *   Form array.
208
 */
209
function nodeaccess_grant_tab($node) {
210
  return drupal_get_form('nodeaccess_grants_form', $node);
211
}
212

    
213
/**
214
 * Menu callback. Draws the grant tab.
215
 *
216
 * @param $form
217
 * @param $form_state
218
 * @param $node
219
 *
220
 * @return mixed
221
 */
222
function nodeaccess_grants_form($form, &$form_state, $node) {
223
  $form_values = $form_state['values'];
224

    
225
  if (!$form_values) {
226
    $form_values = array();
227
    $grants = nodeaccess_get_grants($node);
228
    $form_values['rid'] = isset($grants['rid']) ? $grants['rid'] : array();
229
    $form_values['uid'] = isset($grants['uid']) ? $grants['uid'] : array();
230
  }
231
  elseif ($form_values['keys']) {
232
    $name = preg_replace('!\*+!', '%', $form_values['keys']);
233
    $uid = array_keys($form_values['uid']);
234

    
235
    $query = db_select('users', 'u')
236
      ->fields('u', array('uid', 'name'))
237
      ->condition('name', $name, "LIKE");
238

    
239
    if (isset($form_values['uid']) && count($form_values['uid'])) {
240
      $query->condition('uid', $uid, 'NOT IN');
241
    }
242

    
243
    $result = $query->execute();
244
    while ($account = $result->fetch()) {
245
      $form_values['uid'][$account->uid] = array(
246
        'name' => $account->name,
247
        'keep' => 1,
248
        'grant_view' => isset($form_values['rid'][DRUPAL_AUTHENTICATED_RID]['grant_view']) ?
249
          $form_values['rid'][DRUPAL_AUTHENTICATED_RID]['grant_view'] : 0,
250
        'grant_update' => isset($form_values['rid'][DRUPAL_AUTHENTICATED_RID]['grant_update']) ?
251
          $form_values['rid'][DRUPAL_AUTHENTICATED_RID]['grant_update'] : 0,
252
        'grant_delete' => isset($form_values['rid'][DRUPAL_AUTHENTICATED_RID]['grant_delete']) ?
253
          $form_values['rid'][DRUPAL_AUTHENTICATED_RID]['grant_delete'] : 0,
254
      );
255
    }
256
  }
257

    
258
  if (!isset($form_values['rid'])) {
259
    $form_values['rid'] = array();
260
  }
261

    
262
  if (!isset($form_values['uid'])) {
263
    $form_values['uid'] = array();
264
  }
265

    
266
  $roles = $form_values['rid'];
267
  $users = $form_values['uid'];
268

    
269
  $form['nid'] = array(
270
    '#type' => 'hidden',
271
    '#value' => $node->nid,
272
  );
273

    
274
  $allowed_roles = variable_get('nodeaccess-roles', array());
275
  $allowed_grants = variable_get('nodeaccess-grants', array());
276
  // If $preserve is TRUE, the fields the user is not allowed to view or
277
  // edit are included in the form as hidden fields to preserve them.
278
  $preserve = variable_get('nodeaccess-preserve', 1);
279
  // Roles table.
280
  if (is_array($roles)) {
281
    $form['rid'] = array('#tree' => TRUE);
282
    foreach ($roles as $key => $field) {
283
      if (isset($allowed_roles[$key]) && $allowed_roles[$key]) {
284
        $form['rid'][$key]['name'] = array(
285
          '#type' => 'hidden',
286
          '#value' => $field['name'],
287
        );
288
        if ($allowed_grants['view']) {
289
          $form['rid'][$key]['grant_view'] = array(
290
            '#type' => 'checkbox',
291
            '#default_value' => $field['grant_view'],
292
          );
293
        }
294
        elseif ($preserve) {
295
          $form['rid'][$key]['grant_view'] = array(
296
            '#type' => 'hidden',
297
            '#value' => $field['grant_view'],
298
          );
299
        }
300
        if ($allowed_grants['edit']) {
301
          $form['rid'][$key]['grant_update'] = array(
302
            '#type' => 'checkbox',
303
            '#default_value' => $field['grant_update'],
304
          );
305
        }
306
        elseif ($preserve) {
307
          $form['rid'][$key]['grant_update'] = array(
308
            '#type' => 'hidden',
309
            '#value' => $field['grant_update'],
310
          );
311
        }
312
        if ($allowed_grants['delete']) {
313
          $form['rid'][$key]['grant_delete'] = array(
314
            '#type' => 'checkbox',
315
            '#default_value' => $field['grant_delete'],
316
          );
317
        }
318
        elseif ($preserve) {
319
          $form['rid'][$key]['grant_delete'] = array(
320
            '#type' => 'hidden',
321
            '#value' => $field['grant_delete'],
322
          );
323
        }
324
      }
325
      elseif ($preserve) {
326
        $form['rid'][$key]['name'] = array(
327
          '#type' => 'hidden',
328
          '#value' => $field['name'],
329
        );
330
        $form['rid'][$key]['grant_view'] = array(
331
          '#type' => 'hidden',
332
          '#value' => $field['grant_view'],
333
        );
334
        $form['rid'][$key]['grant_update'] = array(
335
          '#type' => 'hidden',
336
          '#value' => $field['grant_update'],
337
        );
338
        $form['rid'][$key]['grant_delete'] = array(
339
          '#type' => 'hidden',
340
          '#value' => $field['grant_delete'],
341
        );
342
      }
343
    }
344
  }
345

    
346
  // Users table.
347
  if (is_array($users)) {
348
    $form['uid'] = array('#tree' => TRUE);
349
    foreach ($users as $key => $field) {
350
      $form['uid'][$key]['name'] = array(
351
        '#type' => 'hidden',
352
        '#value' => $field['name'],
353
      );
354
      $form['uid'][$key]['keep'] = array(
355
        '#type' => 'checkbox',
356
        '#default_value' => $field['keep'],
357
      );
358
      if ($allowed_grants['view']) {
359
        $form['uid'][$key]['grant_view'] = array(
360
          '#type' => 'checkbox',
361
          '#default_value' => $field['grant_view'],
362
        );
363
      }
364
      elseif ($preserve) {
365
        $form['uid'][$key]['grant_view'] = array(
366
          '#type' => 'hidden',
367
          '#value' => $field['grant_view'],
368
        );
369
      }
370
      if ($allowed_grants['edit']) {
371
        $form['uid'][$key]['grant_update'] = array(
372
          '#type' => 'checkbox',
373
          '#default_value' => $field['grant_update'],
374
        );
375
      }
376
      elseif ($preserve) {
377
        $form['uid'][$key]['grant_update'] = array(
378
          '#type' => 'hidden',
379
          '#value' => $field['grant_update'],
380
        );
381
      }
382
      if ($allowed_grants['delete']) {
383
        $form['uid'][$key]['grant_delete'] = array(
384
          '#type' => 'checkbox',
385
          '#default_value' => $field['grant_delete'],
386
        );
387
      }
388
      elseif ($preserve) {
389
        $form['uid'][$key]['grant_delete'] = array(
390
          '#type' => 'hidden',
391
          '#value' => $field['grant_delete'],
392
        );
393
      }
394
    }
395
  }
396

    
397
  // Autocomplete returns errors if users don't have access to profiles.
398
  if (user_access('access user profiles')) {
399
    $form['keys'] = array(
400
      '#type' => 'textfield',
401
      '#default_value' => isset($form_values['keys']) ? $form_values['keys'] : '',
402
      '#size' => 40,
403
      '#autocomplete_path' => 'user/autocomplete',
404
    );
405
  }
406
  else {
407
    $form['keys'] = array(
408
      '#type' => 'textfield',
409
      '#default_value' => isset($form_values['keys'])? $form_values['keys'] : '',
410
      '#size' => 40,
411
    );
412
  }
413

    
414
  $form['search'] = array(
415
    '#type' => 'submit',
416
    '#value' => t('Search'),
417
  );
418

    
419
  $form['submit'] = array(
420
    '#type' => 'submit',
421
    '#value' => t('Save Grants'),
422
  );
423

    
424
  return $form;
425
}
426

    
427

    
428
/**
429
 * Validate function for nodeaccess_grants_form.
430
 *
431
 * @param array $form
432
 * @param array &$form_state
433
 */
434
function nodeaccess_grants_form_validate($form, &$form_state) {
435
  $form_values = &$form_state['values'];
436

    
437
  // Delete unkept users.
438
  if (isset($form_values['uid']) && is_array($form_values['uid'])) {
439
    foreach ($form_values['uid'] as $uid => $row) {
440
      if (!$row['keep']) {
441
        unset($form_values['uid'][$uid]);
442
      }
443
    }
444
  }
445

    
446
  if (!isset($form_values['uid'])) {
447
    unset($form_values['uid']);
448
  }
449
}
450

    
451
/**
452
 * Submit function for nodeaccess_grants_form.
453
 *
454
 * @param array $form
455
 * @param array &$form_state
456
 */
457
function nodeaccess_grants_form_submit($form, &$form_state) {
458

    
459
  if ($form_state['clicked_button']['#id'] == 'edit-search') {
460
    $form_state['rebuild'] = TRUE;
461
    $form_state['storage']['values'] = $form_state['values'];
462
  }
463
  else {
464
    unset($form_state['rebuild']);
465
    _nodeaccess_grants_form_submit($form, $form_state);
466
    drupal_set_message(t('Grants saved.'));
467
  }
468
}
469

    
470

    
471
/**
472
 * Private function to submit the per-node grants table.
473
 *
474
 * @param array $form
475
 * @param array &$form_state
476
 */
477
function _nodeaccess_grants_form_submit($form, &$form_state) {
478
  $form_values = &$form_state['values'];
479

    
480
  $grants = array();
481
  $nid = $form_values['nid'];
482
  $node = node_load($nid);
483

    
484
  foreach (array('uid', 'rid') as $type) {
485
    $realm = 'nodeaccess_' . $type;
486

    
487
    if (isset($form_values[$type]) && is_array($form_values[$type])) {
488
      foreach ($form_values[$type] as $gid => $line) {
489
        $grant = array(
490
          'gid' => $gid,
491
          'realm' => $realm,
492
          'grant_view' => empty($line['grant_view']) ? 0 : 1,
493
          'grant_update' => empty($line['grant_update']) ? 0 : 1,
494
          'grant_delete' => empty($line['grant_delete']) ? 0 : 1,
495
        );
496
        $grants[] = $grant;
497
      }
498
    }
499
  }
500
  nodeaccess_set_grants($node, $grants);
501
}
502

    
503
/**
504
 * Theme function for nodeaccess_grants_form.
505
 *
506
 * @param array $vars
507
 *
508
 * @return string
509
 */
510
function theme_nodeaccess_grants_form($vars) {
511
  $output = '';
512

    
513
  $form = $vars['form'];
514
  $rows = array();
515
  $allowed_roles = variable_get('nodeaccess-roles', array());
516
  $allowed_grants = variable_get('nodeaccess-grants', array());
517
  // Retrieve role names for columns.
518
  $role_names = user_roles();
519
  $role_aliases = nodeaccess_get_role_aliases();
520

    
521
  // Replace names with aliases.
522
  foreach ($role_names as $rid => $name) {
523
    if (isset($role_aliases[$rid]['alias'])) {
524
      $role_names[$rid] = $role_aliases[$rid]['alias'];
525
    }
526
  }
527

    
528
  // Roles table.
529
  $roles = element_children($form['rid']);
530

    
531
  if (count($roles) && count($allowed_roles)) {
532
    $header = array();
533
    $header[] = t('Role');
534

    
535
    if ($allowed_grants['view']) {
536
      $header[] = t('View');
537
    }
538

    
539
    if ($allowed_grants['edit']) {
540
      $header[] = t('Edit');
541
    }
542

    
543
    if ($allowed_grants['delete']) {
544
      $header[] = t('Delete');
545
    }
546

    
547
    foreach ($roles as $key) {
548

    
549
      if (isset($allowed_roles[$key]) && $allowed_roles[$key]) {
550
        $row = array();
551
        $row[] = $role_names[$key] . drupal_render($form['rid'][$key]['name']);
552

    
553
        if ($allowed_grants['view']) {
554
          $row[] = drupal_render($form['rid'][$key]['grant_view']);
555
        }
556

    
557
        if ($allowed_grants['edit']) {
558
          $row[] = drupal_render($form['rid'][$key]['grant_update']);
559
        }
560

    
561
        if ($allowed_grants['delete']) {
562
          $row[] = drupal_render($form['rid'][$key]['grant_delete']);
563
        }
564
        $rows[] = $row;
565
      }
566
    }
567
    $output .= theme('table', array('header' => $header, 'rows' => $rows));
568
  }
569

    
570
  // Search form.
571
  $output .= '<p><div class="search-form">';
572
  $output .= '<strong>' . t('Enter names to search for users:') . '</strong>';
573
  $output .= '<div class="container-inline">';
574
  $output .= drupal_render($form['keys']);
575
  $output .= drupal_render($form['search']);
576
  $output .= '</div></div></p>';
577

    
578
  // Users table.
579
  unset($rows);
580
  $users = element_children($form['uid']);
581

    
582
  if (count($users) > 0) {
583
    $header = array();
584
    $rows = array();
585
    $header[] = t('User');
586
    $header[] = t('Keep?');
587
    if ($allowed_grants['view']) {
588
      $header[] = t('View');
589
    }
590
    if ($allowed_grants['edit']) {
591
      $header[] = t('Edit');
592
    }
593
    if ($allowed_grants['delete']) {
594
      $header[] = t('Delete');
595
    }
596
    foreach ($users as $key) {
597
      $row = array();
598
      $row[] = $form['uid'][$key]['name']['#value'];
599
      $row[] = drupal_render($form['uid'][$key]['keep']);
600
      if ($allowed_grants['view']) {
601
        $row[] = drupal_render($form['uid'][$key]['grant_view']);
602
      }
603
      if ($allowed_grants['edit']) {
604
        $row[] = drupal_render($form['uid'][$key]['grant_update']);
605
      }
606
      if ($allowed_grants['delete']) {
607
        $row[] = drupal_render($form['uid'][$key]['grant_delete']);
608
      }
609
      $rows[] = $row;
610
    }
611
    $output .= theme('table', array('header' => $header, 'rows' => $rows));
612
  }
613

    
614
  $output .= drupal_render_children($form);
615

    
616
  return $output;
617
}
618

    
619

    
620
/**
621
 * Implements hook_node_grants().
622
 *
623
 * @param Object $account
624
 * @parap string $op
625
 *
626
 * @return array
627
 */
628
function nodeaccess_node_grants($account, $op) {
629
  $roles = is_array($account->roles) ? array_keys($account->roles) : array(-1);
630
  return array(
631
    'nodeaccess_rid' => $roles,
632
    'nodeaccess_uid' => array($account->uid),
633
    'nodeaccess_author' => array($account->uid),
634
  );
635
}
636

    
637
/**
638
 * Implements hook_node_update().
639
 *
640
 * @param Object $node
641
 */
642
function nodeaccess_node_update($node) {
643
  if (module_exists('user_reference')) {
644
    $fields = variable_get('nodeaccess_' . $node->type . '_user_reference', array());
645
    foreach (array_keys($fields) as $field_name) {
646
      if (isset($node->$field_name)) {
647
        $old_node = node_load($node->nid);
648
        // Delete the old user as it's changed.
649
        if ($node->$field_name != $old_node->$field_name) {
650
          nodeaccess_delete_user_reference($old_node);
651
          nodeaccess_insert_user_reference($node);
652
        }
653
        break;
654
      }
655
    }
656
  }
657
  // Done, author permissions are not written into nodeaccess.
658
}
659

    
660
/**
661
 * Implements hook_node_delete().
662
 *
663
 * @param Object $node
664
 */
665
function nodeaccess_node_delete($node) {
666
  // Deleting node, delete related permissions.
667
  nodeaccess_delete_grants($node);
668
}
669

    
670
/**
671
 * Implements hook_node_access_records().
672
 *
673
 * @param Object $node
674
 *
675
 * @return array|NULL
676
 */
677
function nodeaccess_node_access_records($node) {
678
  if (nodeaccess_disabling() || !$node->status) {
679
    return NULL;
680
  }
681

    
682
  // Need to find out if node has own grants or whether to use defaults.
683
  $default = variable_get('nodeaccess_' . $node->type, array());
684

    
685
  // Setup default keys that are required by node_access_write_grants().
686
  $grant_defaults = array(
687
    'gid' => 0,
688
    'realm' => 'nodeaccess_rid',
689
    'grant_view' => 0,
690
    'grant_update' => 0,
691
    'grant_delete' => 0,
692
    'priority' => variable_get('nodeaccess-priority', 0),
693
  );
694

    
695
  $query = db_select('nodeaccess', 'n')
696
    ->fields('n', array('gid', 'realm', 'grant_view', 'grant_update', 'grant_delete'))
697
    ->condition('nid', $node->nid, '=');
698
  $result = $query->execute();
699
  if (!$result->rowCount()) {
700
    // Node has no own grants, use defaults.
701
    $grants = $default;
702
  }
703
  else {
704
    // Node has own grants, use them.
705
    $grants = array();
706
    while ($row = $result->fetchAssoc()) {
707
      $grants[] = $row;
708
    }
709
  }
710

    
711
  // Apply author grants.
712
  $author_prefs = variable_get('nodeaccess_authors', array());
713
  // Array is pre-populated with grant values.
714
  $grant = $author_prefs[$node->type];
715
  $grant['gid'] = $node->uid;
716
  $grant['realm'] = 'nodeaccess_author';
717
  // Include author grant even with all values FALSE, it may be
718
  // needed to overwrite an older value.
719
  $grants[] = $grant;
720

    
721
  foreach ($grants as $id => $grant) {
722
    // Merge missing default grant keys.
723
    $grants[$id] = $grants[$id] + $grant_defaults;
724
  }
725

    
726
  return $grants;
727
}
728

    
729

    
730
/**
731
 * Mark module to be in process of disabling.
732
 *
733
 * Prevents entries being saved to node_access while module is being disabled.
734
 *
735
 * @param mixed $set
736
 *   A boolean set or NULL to not change status.
737
 *
738
 * @return bool
739
 */
740
function nodeaccess_disabling($set = NULL) {
741
  static $disabling = FALSE;
742

    
743
  if ($set !== NULL) {
744
    $disabling = $set;
745
  }
746

    
747
  return $disabling;
748
}
749

    
750

    
751
/**
752
 * Implements hook_node_type_delete().
753
 *
754
 * @param Object $info
755
 */
756
function nodeaccess_node_type_delete($info) {
757
  // Node type is being deleted, delete its preferences.
758
  variable_del('nodeaccess_' . $info->type);
759
  $author_prefs = variable_get('nodeaccess_authors', array());
760
  unset($author_prefs[$info->type]);
761
  variable_set('nodeaccess_authors', $author_prefs);
762
}
763

    
764

    
765
/**
766
 * Implements hook_node_type_update().
767
 *
768
 * @param Object $info
769
 */
770
function nodeaccess_node_type_update($info) {
771
  // Node type has changed, move preferences to new type.
772
  if (!empty($info->old_type) && $info->old_type != $info->type) {
773
    $setting = variable_get('nodeaccess_' . $info->old_type, array());
774
    variable_del('nodeaccess_' . $info->old_type);
775
    variable_set('nodeaccess_' . $info->type, $setting);
776
    $author_prefs = variable_get('nodeaccess_authors', array());
777
    $author_prefs[$info->type] = array(
778
      'grant_view' => $author_prefs[$info->old_type]['grant_view'],
779
      'grant_update' => $author_prefs[$info->old_type]['grant_update'],
780
      'grant_delete' => $author_prefs[$info->old_type]['grant_delete'],
781
    );
782
    unset($author_prefs[$info->old_type]);
783
    variable_set('nodeaccess_authors', $author_prefs);
784
  }
785
}
786

    
787

    
788
/**
789
 * Implements hook_node_type_insert().
790
 *
791
 * @param Object $info
792
 */
793
function nodeaccess_node_type_insert($info) {
794
  // New node type, default to whatever is set for access content permission.
795
  $role_perms = user_role_permissions(array(1 => 1, 2 => 2));
796
  $role_perms[DRUPAL_ANONYMOUS_RID]['access content'] = isset($role_perms[1]['access content']) ?
797
                                      intval($role_perms[1]['access content']) : 0;
798
  $role_perms[DRUPAL_AUTHENTICATED_RID]['access content'] = isset($role_perms[2]['access content']) ?
799
                                      intval($role_perms[2]['access content']) : 0;
800
  $grants[] = array(
801
    'gid' => DRUPAL_ANONYMOUS_RID,
802
    'realm' => 'nodeaccess_rid',
803
    'grant_view' => $role_perms[DRUPAL_ANONYMOUS_RID]['access content'],
804
    'grant_update' => 0,
805
    'grant_delete' => 0,
806
  );
807
  $grants[] = array(
808
    'gid' => DRUPAL_AUTHENTICATED_RID,
809
    'realm' => 'nodeaccess_rid',
810
    'grant_view' => $role_perms[DRUPAL_AUTHENTICATED_RID]['access content'],
811
    'grant_update' => 0,
812
    'grant_delete' => 0,
813
  );
814
  variable_set('nodeaccess_' . $info->type, $grants);
815

    
816
  // Add permissions for author.
817
  $author_prefs = variable_get('nodeaccess_authors', array());
818
  $author_prefs[$info->type] = array(
819
    'grant_view' => 0,
820
    'grant_update' => 0,
821
    'grant_delete' => 0,
822
  );
823

    
824
  variable_set('nodeaccess_authors', $author_prefs);
825
  node_access_needs_rebuild(TRUE);
826
}
827

    
828

    
829
/**
830
 * Retrieve role aliases.
831
 *
832
 * @return array
833
 *  Role aliases indexed by rid.
834
 */
835
function nodeaccess_get_role_aliases() {
836
  $aliases = array();
837
  $query = db_select('role', 'r');
838
  $query->join('nodeaccess_role_alias', 'a', 'r.rid = a.rid');
839
  $query->fields('r', array('rid', 'name'));
840
  $query->addField('a', 'name', 'alias');
841
  $query->addField('a', 'weight');
842
  $query->orderBy('a.weight');
843
  $query->orderBy('r.weight');
844
  $query->orderBy('a.name');
845
  $query->orderBy('r.name');
846
  $result = $query->execute();
847
  while($a = $result->fetch()) {
848
    $aliases[$a->rid]['name'] = $a->name;
849
    $aliases[$a->rid]['alias'] = $a->alias;
850
    $aliases[$a->rid]['weight'] = $a->weight;
851
  }
852
  return $aliases;
853
}
854

    
855
/**
856
 * Save a role alias.
857
 *
858
 * @param array $edit
859
 *   An array of aliases to save, indexed by rid.
860
 */
861
function nodeaccess_save_role_aliases($edit) {
862
  db_delete('nodeaccess_role_alias')->execute();
863
  if (is_array($edit)) {
864
    foreach ($edit as $key => $value) {
865
      db_insert('nodeaccess_role_alias')->fields(array(
866
        'rid' => $key,
867
        'name' => $value['name'],
868
        'weight' => $value['weight'],
869
      ))->execute();
870
    }
871
  }
872
  return;
873
}
874

    
875
/**
876
 * Insert userreference grants from a node.
877
 *
878
 * @param Object $node
879
 */
880
function nodeaccess_insert_user_reference($node) {
881
  $form_values = nodeaccess_get_grants($node);
882
  // Now, append or overwrite the uid with what was specified in the user
883
  // reference field.
884
  $fields = variable_get('nodeaccess_' . $node->type . '_user_reference', array());
885
  foreach ($fields as $field_name => $field) {
886
    $user_uids = field_get_items('node', $node, $field_name);
887
    $user_references = user_load_multiple($user_uids);
888
    // Add each of the referenced users a form value.
889
    foreach ($user_references as $user) {
890
      $form_values['uid'][$user->uid] = array(
891
        'name' => $user->name,
892
        'keep' => 1,
893
        'grant_view' => $field['grant_view'],
894
        'grant_update' => $field['grant_update'],
895
        'grant_delete' => $field['grant_delete'],
896
      );
897
    }
898
  }
899
  // Only do the changes if there are users to save.
900
  if (count($form_values['uid']) > 0) {
901
    $form_values['nid'] = $node->nid;
902
    $form_state = array('values' => $form_values);
903
    _nodeaccess_grants_form_submit(NULL, $form_state);
904
  }
905
}
906

    
907
/**
908
 * Delete all userreference user grants from a node.
909
 *
910
 * @param Object $node
911
 */
912
function nodeaccess_delete_user_reference($node) {
913
  $form_values = nodeaccess_get_grants($node);
914
  // Now, append or overwrite the uid with what was specified in the user
915
  // reference field.
916
  $fields = variable_get('nodeaccess_' . $node->type . '_user_reference', array());
917
  foreach ($fields as $field_name => $field) {
918
    $user_uids = field_get_items('node', $node, $field_name);
919
    $user_references = user_load_multiple($user_uids);
920
    foreach ($user_references as $user) {
921
      unset($form_values['uid'][$user->uid]);
922
    }
923
  }
924
  $form_values['nid'] = $node->nid;
925
  $form_state = array('values' => $form_values);
926

    
927
  _nodeaccess_grants_form_submit(NULL, $form_state);
928
}
929

    
930
/**
931
 * Return the grants applied to a node object used for Grant form.
932
 *
933
 * @param Object $node
934
 *
935
 * @return array
936
 *   An array of grants with keys 'rid' for roles and 'uid' for users.
937
 */
938
function nodeaccess_get_grants($node) {
939
  $grants = array();
940

    
941
  // Load grants by roles.
942
  $query = db_select('nodeaccess', 'na');
943
  $query->join('role', 'r', 'r.rid = na.gid');
944
  $query->join('nodeaccess_role_alias', 'nra', 'nra.rid = r.rid');
945
  $query->fields('r', array('rid', 'name'));
946
  $query->fields('na', array('grant_view', 'grant_update', 'grant_delete'));
947
  $query->condition('na.realm', 'nodeaccess_rid', '=');
948
  $query->condition('na.nid', $node->nid, '=');
949
  $query->orderBy('nra.weight');
950
  $query->orderBy('nra.name');
951
  $result = $query->execute();
952

    
953
  while ($grant = $result->fetch()) {
954
    if ($grant->name) {
955
      $grants['rid'][$grant->rid] = array(
956
        'name' => $grant->name,
957
        'grant_view' => (bool) $grant->grant_view,
958
        'grant_update' => (bool) $grant->grant_update,
959
        'grant_delete' => (bool) $grant->grant_delete,
960
      );
961
    }
962
  }
963
  // Load grants by users
964
  $query = db_select('node_access', 'na');
965
  $query->join('users', 'u', 'u.uid = na.gid');
966
  $query->fields('u', array('uid', 'name'));
967
  $query->fields('na', array('grant_view', 'grant_update', 'grant_delete'));
968
  $query->condition('na.nid', $node->nid, '=');
969
  $query->condition('na.realm', 'nodeaccess_uid', '=');
970
  $query->orderBy('name');
971
  $result = $query->execute();
972

    
973
  while ($account = $result->fetch()) {
974
    $grants['uid'][$account->uid] = array(
975
      'name' => $account->name,
976
      'keep' => TRUE,
977
      'grant_view' => (bool) $account->grant_view,
978
      'grant_update' => (bool) $account->grant_update,
979
      'grant_delete' => (bool) $account->grant_delete,
980
    );
981
  }
982
  return $grants;
983
}
984

    
985
/**
986
 * Set all grants for a node to nodeaccess table and acquire them.
987
 *
988
 * @param $node
989
 *   node object the grants are being applied to.
990
 * @param array $grants
991
 *   array of grants as defined (@see nodeaccess_save_grant).
992
 */
993
function nodeaccess_set_grants($node, $grants = array()) {
994
  // Allow other modules to edit all grants for array.
995
  drupal_alter('nodeaccess_grants', $grants, $node);
996

    
997
  nodeaccess_delete_grants($node);
998

    
999
  if (count($grants)) {
1000
    foreach ($grants as $grant) {
1001
      // Allow other modules to edit single grants.
1002
      drupal_alter('nodeaccess_grant', $grant, $node);
1003
      nodeaccess_save_grant($node, $grant);
1004
    }
1005
  }
1006

    
1007
  node_access_acquire_grants($node);
1008
}
1009

    
1010

    
1011
/**
1012
 * Delete all grants from nodeaccess table for this node.
1013
 *
1014
 * @param $node
1015
 *   node object whose grants are being revoked.
1016
 */
1017
function nodeaccess_delete_grants($node) {
1018
  try {
1019
    db_delete('nodeaccess')
1020
      ->condition('nid', $node->nid)
1021
      ->execute();
1022

    
1023
    node_access_acquire_grants($node);
1024
  }
1025
  catch (Exception $e) {
1026
    drupal_set_message(t("Database error has occurred while clearing nodeaccess table."), 'error');
1027
    watchdog('nodeaccess', 'Database error: @message.', array('@message' => $e->getMessage()), WATCHDOG_ERROR);
1028
  }
1029
}
1030

    
1031
/**
1032
 * Revoke all custom grants from nodeaccess table for this node.  Essentially
1033
 * reset the grants to their default state (by node type).
1034
 *
1035
 * @param $node
1036
 *   node object whose grants are being revoked.
1037
 */
1038
function nodeaccess_revoke_grants($node) {
1039
  nodeaccess_delete_grants($node);
1040
  node_access_acquire_grants($node);
1041
}
1042

    
1043
/**
1044
 * Save the grant settings/options for the node.
1045
 *
1046
 * @param $node
1047
 *   node object the grant is being applied to.
1048
 * @param array $grant
1049
 *   array(
1050
 *    'gid' => (int) gid for realm,
1051
 *    'realm' => (string) what realm the access grant belongs to (ex: nodeaccess_rid).
1052
 *    'grant_view' => (int) view access being granted,
1053
 *    'grant_update' => (int) update access being granted,
1054
 *    'grant_delete' => (int) delete access being granted,
1055
 *  )
1056
 */
1057
function nodeaccess_save_grant($node, $grant) {
1058
  // Save role and user grants to our own table.
1059
  try {
1060
    db_insert('nodeaccess')
1061
      ->fields(array(
1062
        'nid' => $node->nid,
1063
        'gid' => $grant['gid'],
1064
        'realm' => $grant['realm'],
1065
        'grant_view' => (int) $grant['grant_view'],
1066
        'grant_update' => (int) $grant['grant_update'],
1067
        'grant_delete' => (int) $grant['grant_delete'],
1068
      ))
1069
      ->execute();
1070
  }
1071
  catch (Exception $e) {
1072
    drupal_set_message(t("Database error has occurred while saving to nodeaccess table."), 'error');
1073
    watchdog('nodeaccess', 'Database error: @message.', array('@message' => $e->getMessage()), WATCHDOG_ERROR);
1074
  }
1075
}
1076

    
1077
/**
1078
 * Add the grant tab to the specified node type.
1079
 *
1080
 * @param string $type
1081
 *   The node type we are adding the grant tab for.
1082
 */
1083
function nodeaccess_add_type_grant($type) {
1084
  $grants = variable_get('nodeaccess-types', array());
1085
  $grants[$type] = TRUE;
1086

    
1087
  nodeaccess_set_type_grants($grants);
1088
}
1089

    
1090
/**
1091
 * Delete the grant tab for specified node type.
1092
 *
1093
 * @param string $type
1094
 *   The node type we are removing the grant tab from.
1095
 */
1096
function nodeaccess_delete_type_grant($type) {
1097
  $grants = variable_get('nodeaccess-types', array());
1098

    
1099
  if (isset($grants[$type])) {
1100
    unset($grants[$type]);
1101
  }
1102

    
1103
  nodeaccess_set_type_grants($grants);
1104
}
1105

    
1106
/**
1107
 * Set the grant tab settings for all node types.
1108
 *
1109
 * @param array $types
1110
 *   The types that will have the grant tab appear.
1111
 *
1112
 */
1113
function nodeaccess_set_type_grants($types = array()) {
1114
  if (!is_array($types)) {
1115
    return;
1116
  }
1117

    
1118
  variable_set('nodeaccess-types', $types);
1119
  node_access_needs_rebuild(TRUE);
1120
}