You are here

simple_access.module in Simple Access 5.2

This module allows administrators to make nodes viewable by specific 'access groups'. Each access group can contain any number of roles. If a node is not assigned to any access groups, it will remain viewable by all users.

Database definition:

File

simple_access.module
View source
<?php

/**
 * @file
 * This module allows administrators to make nodes viewable by specific
 * 'access groups'. Each access group can contain any number of roles.
 * If a node is not assigned to any access groups, it will remain viewable 
 * by all users.
 *
 * Database definition:
 * @code
 * @endcode
 *
 */

/**
 * Check if Workflow NG is installed and load include
 */
if (module_exists('workflow_ng')) {
  include_once './' . drupal_get_path('module', 'simple_access') . '/inc/workflow_ng.inc';
}

/**
 * Implementation of hook_menu().
 */
function simple_access_menu($may_cache) {
  $access = user_access('manage simple access');
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/user/simple_access',
      'title' => t('Access groups'),
      'access' => $access,
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'simple_access_page_overview',
      ),
      'type' => MENU_NORMAL_ITEM,
      'description' => t('Manage groups of users for node-specific access control.'),
    );
    $items[] = array(
      'path' => 'admin/user/simple_access/list',
      'title' => t('List'),
      'access' => $access,
      'type' => MENU_DEFAULT_LOCAL_TASK,
      'weight' => -8,
    );
    $items[] = array(
      'path' => 'admin/user/simple_access/add',
      'title' => t('Add Group'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'simple_access_group_form',
      ),
      'access' => $access,
      'type' => MENU_LOCAL_TASK,
      'weight' => -6,
    );
    $items[] = array(
      'path' => 'admin/user/simple_access/edit',
      'title' => t('Edit Group'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'simple_access_group_form',
      ),
      'access' => $access,
      'type' => MENU_CALLBACK,
    );
    $items[] = array(
      'path' => 'admin/user/simple_access/delete',
      'title' => t('Delete Group'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'simple_access_delete_group_confirm',
      ),
      'access' => $access,
      'type' => MENU_CALLBACK,
    );
    $items[] = array(
      'path' => 'admin/user/sa_profiles',
      'title' => t('Access profiles'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'simple_access_profile_list',
      ),
      'access' => $access,
      'type' => MENU_NORMAL_ITEM,
      'description' => t('Maintain access profiles'),
    );
    $items[] = array(
      'path' => 'admin/user/sa_profiles/list',
      'title' => t('List'),
      'access' => $access,
      'type' => MENU_DEFAULT_LOCAL_TASK,
      'weight' => -9,
    );
    $items[] = array(
      'path' => 'admin/user/sa_profiles/add',
      'title' => t('Add'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'simple_access_profile_form',
      ),
      'access' => $access,
      'type' => MENU_LOCAL_TASK,
    );
    $items[] = array(
      'path' => 'admin/settings/simple_access',
      'title' => t('Simple Access'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'simple_access_settings_page',
      ),
      'access' => $access,
      'type' => MENU_NORMAL_ITEM,
      'description' => t('Configure which kinds of access (view, edit, delete) users with permission to use Simple Access can define for each node.'),
    );
    $items[] = array(
      'path' => 'admin/content/simple_access',
      'title' => t('Simple Access'),
      'access' => user_access('administer nodes'),
      'callback' => 'simple_access_nodes',
      'type' => MENU_NORMAL_ITEM,
      'description' => t('View node access which has been set up via Simple Access.'),
    );
    $items[] = array(
      'path' => 'admin/content/simple_access/view',
      'title' => t('View'),
      'callback' => 'simple_access_nodes',
      'access' => user_access('administer nodes'),
      'type' => MENU_DEFAULT_LOCAL_TASK,
      'weight' => -5,
    );
    $items[] = array(
      'path' => 'admin/content/simple_access/edit',
      'title' => t('Edit Access'),
      'callback' => 'simple_access_nodes',
      'access' => user_access('administer nodes'),
      'type' => MENU_CALLBACK,
      'weight' => -4,
    );
    $items[] = array(
      'path' => 'admin/content/simple_access/delete',
      'title' => t('Delete Access'),
      'callback' => 'simple_access_nodes',
      'access' => user_access('administer nodes'),
      'type' => MENU_CALLBACK,
      'weight' => -3,
    );
  }
  else {
    if (arg(0) == 'admin' && arg(1) == 'user' && arg(2) == 'sa_profiles' && is_numeric(arg(3))) {
      $items[] = array(
        'path' => 'admin/user/sa_profiles/' . arg(3) . '/edit',
        'title' => t('Edit Profile'),
        'callback' => 'drupal_get_form',
        'callback arguments' => array(
          'simple_access_profile_form',
          arg(3),
        ),
        'access' => $access,
        'type' => MENU_CALLBACK,
      );
      $items[] = array(
        'path' => 'admin/user/sa_profiles/' . arg(3) . '/delete',
        'title' => t('Delete Profile'),
        'callback' => 'drupal_get_form',
        'callback arguments' => array(
          'simple_access_profile_delete_confirm',
          arg(3),
        ),
        'access' => $access,
        'type' => MENU_CALLBACK,
      );
    }
  }
  return $items;
}

/**
 * Implementation of hook_perm().
 */
function simple_access_perm() {
  return array(
    'manage simple access',
    'assign access to nodes',
    'assign profiles to profiles',
    'assign owner permissions',
  );
}

/**
 * Implementation of hook_nodeapi()
 */
function simple_access_nodeapi(&$node, $op) {
  switch ($op) {
    case 'prepare':
      if (empty($node->simple_access_owner)) {
        $node->simple_access_owner = array(
          'sa_view' => 0,
          'sa_update' => 0,
          'sa_delete' => 0,
        );
      }
      if (empty($node->simple_access)) {
        $node->simple_access = array();
      }
      if (empty($node->simple_access_profiles)) {
        $node->simple_access_profiles = array();
      }
      break;
    case 'load':
      if ($row = db_fetch_array(db_query('SELECT no.sa_view, no.sa_update, no.sa_delete FROM {simple_access_owner} no WHERE no.nid = %d', $node->nid))) {
        $node->simple_access_owner = $row;
      }
      else {
        $node->simple_access_owner = array(
          'sa_view' => 0,
          'sa_update' => 0,
          'sa_delete' => 0,
        );
      }
      $extra = array();
      $result = db_query('SELECT na.gid, na.sa_view, na.sa_update, na.sa_delete FROM {simple_access_node} na WHERE na.nid = %d', $node->nid);
      while ($grant = db_fetch_array($result)) {
        $gid = $grant['gid'];
        unset($grant['gid']);
        $extra[$gid] = $grant;
      }
      $node->simple_access = $extra;
      $result = db_query('SELECT pid FROM {simple_access_profiles_node} WHERE nid = %d', $node->nid);
      while ($row = db_fetch_array($result)) {
        $node->simple_access_profiles[] = $row['pid'];
      }
      break;
    case 'update':
    case 'insert':
      if ($node->uid) {
        $node->simple_access_owner['nid'] = $node->nid;
        db_query('UPDATE {simple_access_owner} o SET o.sa_view = %d, o.sa_update = %d, o.sa_delete = %d WHERE o.nid = %d', array_values($node->simple_access_owner));
        if (!db_affected_rows()) {
          db_query('INSERT INTO {simple_access_owner} (sa_view, sa_update, sa_delete, nid) VALUES (%d, %d, %d, %d)', $node->simple_access_owner);
        }
      }
      db_query('DELETE FROM {simple_access_node} WHERE nid = %d', $node->nid);
      if (isset($node->simple_access)) {
        foreach ($node->simple_access as $gid => $access) {
          if ($access['sa_view'] || $access['sa_update'] || $access['sa_delete']) {
            db_query("INSERT INTO {simple_access_node} (nid, gid, sa_view, sa_update, sa_delete) VALUES (%d, %d, %d, %d, %d)", $node->nid, $gid, $access['sa_view'], $access['sa_update'], $access['sa_delete']);
          }
        }
      }
      db_query('DELETE FROM {simple_access_profiles_node} WHERE nid = %d', $node->nid);
      if (isset($node->simple_access_profiles)) {
        foreach (array_filter($node->simple_access_profiles) as $pid) {
          db_query('INSERT INTO {simple_access_profiles_node} (nid, pid) VALUES (%d, %d)', $node->nid, $pid);
        }
      }
      break;
    case 'delete':
      db_query('DELETE FROM {simple_access_node} WHERE nid = %d', $node->nid);
      db_query('DELETE FROM {simple_access_owner} WHERE nid = %d', $node->nid);
      db_query('DELETE FROM {simple_access_profiles_node} WHERE nid = %d', $node->nid);
      break;
  }
}

/**
 * Implementation of hook_node_access_records
 */
function simple_access_node_access_records($node) {
  $records = array();
  if ($node->simple_access_profiles) {
    foreach (array_filter($node->simple_access_profiles) as $pid) {
      $records[] = array(
        'realm' => 'simple_access_profile',
        'gid' => $pid,
        'grant_view' => 1,
        'grant_update' => 1,
        'grant_delete' => 1,
        'priority' => 1,
      );
    }
  }
  if ($node->simple_access) {

    // loop through simple_access arrays from page submission
    // $type is either 'view', 'update', or 'delete'
    foreach ($node->simple_access as $gid => $access) {
      if ($access['sa_view'] || $access['sa_update'] || $access['sa_delete']) {
        $records[] = array(
          'realm' => 'simple_access',
          'gid' => $gid,
          'grant_view' => $access['sa_view'],
          'grant_update' => $access['sa_update'],
          'grant_delete' => $access['sa_delete'],
          'priority' => 1,
        );
      }
    }
  }
  if ($node->uid && ($node->simple_access_owner['sa_view'] || $node->simple_access_owner['sa_update'] || $node->simple_access_owner['sa_delete'])) {
    $records[] = array(
      'realm' => 'simple_access_author',
      'gid' => $node->uid,
      'grant_view' => $node->simple_access_owner['sa_view'],
      'grant_update' => $node->simple_access_owner['sa_update'],
      'grant_delete' => $node->simple_access_owner['sa_delete'],
      'priority' => 1,
    );
  }
  return $records;
}

/**
 * Implementation of hook_node_grants().
 *
 *  @TODO implement to correcly return groups in all cases.
 */
function simple_access_node_grants($account, $op) {
  $gids = simple_access_groups_from_roles(array_keys($account->roles));
  $grants['simple_access'] = $gids;
  if (in_array($op, array(
    'view',
    'update',
    'delete',
  )) && !empty($gids)) {
    $result = db_query('SELECT DISTINCT pid FROM {simple_access_profiles_access} WHERE sa_' . $op . ' = 1 AND gid in (' . implode(',', array_fill(0, count($gids), '%d')) . ')', $gids);
    while ($row = db_fetch_array($result)) {
      $pids[] = $row['pid'];
    }
    if (!empty($pids)) {
      $grants['simple_access_profiles'] = $pids;
    }
  }
  $grants['simple_access_author'] = array(
    $account->uid,
  );
  return $grants;
}

/**
 * Implementation of hook_node_access_explain()
 */
function simple_access_node_access_explain($row) {
  switch ($row->realm) {
    case 'simple_access_author':
      return t('Access for the content owner');
    case 'simple_access':
      $groups = simple_access_get_groups();
      return t('Access restrictions for the "%group" group', array(
        '%group' => $groups[$row->gid]['name'],
      ));
    case 'simple_access_profile':
      $groups = simple_access_get_groups();
      $profiles = simple_access_get_profiles();
      $profile = $profiles[$row->gid];
      $message = t('Access restrictions for profile "%profile"<br /><dt>', array(
        '%profile' => $profile['name'],
      ));
      if (!empty($profile['access'])) {
        foreach ($profile['access'] as $gid => $access) {
          $message .= t(' "%group" group can @perm.', array(
            '%group' => $groups[$gid]['name'],
            '@perm' => implode(', ', array_keys(array_filter($access))),
          ));
        }
      }
      $message .= '</dt>';
      return $message;
  }
}
function simple_access_form_alter($form_id, &$form) {

  // if this is a node form...
  if (isset($form['type']) && $form['type']['#value'] . '_node_form' == $form_id) {
    if ($simple_access_form = simple_access_form($form['#node'])) {
      $form = array_merge($form, $simple_access_form);
    }
  }
}
function simple_access_form($node) {

  // Get the array of checkbox options to use for each form element.
  // If the "Show groups even when user is not a member" setting is
  // enabled, or if the current user has 'administer nodes', let
  // them choose from any of the SA groups.
  $groups = simple_access_group_select();
  $profiles = simple_access_get_profiles_select();
  if (empty($groups) && empty($profiles) && !user_access('assign owner permissions')) {
    return;
  }
  $user_groups = array_filter($node->simple_access, '_simple_access_filter_access');
  $owner_priv = array_filter($node->simple_access_owner);

  // set up the outer fieldset
  $form['sa'] = array(
    '#title' => t('Access'),
    '#type' => 'fieldset',
    '#collapsible' => TRUE,
    '#collapsed' => empty($user_groups) && empty($node->simple_access_profiles) && empty($owner_priv),
    '#access' => user_access('assign access to profiles') || user_access('assign access to nodes') || user_access('administer nodes'),
  );
  if (!empty($profiles)) {
    $form['sa']['simple_access_profiles'] = array(
      '#type' => 'checkboxes',
      '#title' => t('Access profile'),
      '#default_value' => $node->simple_access_profiles,
      '#options' => $profiles,
      '#access' => user_access('assign access to profiles') || user_access('administer nodes'),
    );
  }
  if (!empty($groups) || user_access('assign owner permissions')) {
    $form['sa']['simple_access'] = array(
      '#tree' => TRUE,
      '#weight' => 5,
      '#access' => user_access('assign access to nodes') || user_access('administer nodes') || user_access('assign owner permissions'),
      '#theme' => 'simple_access_form',
    );

    // Load the owner perminisions.
    $group = array(
      'name' => t('Owner permissions'),
      'access' => user_access('assign owner permissions') && $node->uid,
    );
    $access = array(
      'owner' => $node->simple_access_owner,
    );
    $form['sa']['simple_access']['owner'] = simple_access_form_row('owner', $group, $access);
    $form['sa']['simple_access']['owner']['#parents'] = array(
      'simple_access_owner',
    );

    // See what form elements we should include. If not configured,
    // only enable the 'view' elements by default.
    $variable = variable_get('sa_display', array(
      'view' => 1,
    ));
    foreach ($groups as $gid => $group) {
      $form['sa']['simple_access'][$gid] = simple_access_form_row($gid, $group, $node->simple_access);
    }
  }
  return $form;
}
function simple_access_form_row($gid, $group, $access) {
  $variable = variable_get('sa_display', array(
    'view' => 1,
    'update' => 0,
    'delete' => 0,
  ));
  $priv = $group['access'] || user_access('administer nodes');
  $form = array(
    '#access' => $priv,
  );
  $form['name'] = array(
    '#value' => $group['name'],
    '#access' => $priv,
  );
  $form['sa_view'] = array(
    '#type' => 'checkbox',
    '#default_value' => $access[$gid]['sa_view'],
    '#access' => $priv && $variable['view'],
  );
  $form['sa_update'] = array(
    '#type' => 'checkbox',
    '#default_value' => $access[$gid]['sa_update'],
    '#access' => $priv && $variable['update'],
  );
  $form['sa_delete'] = array(
    '#type' => 'checkbox',
    '#default_value' => $access[$gid]['sa_delete'],
    '#access' => $priv && $variable['delete'],
  );
  return $form;
}
function theme_simple_access_form($form) {
  drupal_add_css(drupal_get_path('module', 'simple_access') . '/simple_access.css');
  $output = '';
  $variable = variable_get('sa_display', array(
    'view' => 1,
  ));
  $head = array(
    t('Access Group'),
  );
  if ($variable['view'] || isset($form['#admin'])) {
    $head[] = t('View');
  }
  if ($variable['update'] || isset($form['#admin'])) {
    $head[] = t('Update');
  }
  if ($variable['delete'] || isset($form['#admin'])) {
    $head[] = t('Delete');
  }
  foreach (element_children($form) as $gid) {
    if (!isset($form['#access']) || $form['#access']) {
      $row = array(
        array(
          'data' => drupal_render($form[$gid]['name']),
        ),
      );
      if ($variable['view'] || isset($form['#admin'])) {
        $row[] = array(
          'data' => drupal_render($form[$gid]['sa_view']),
        );
      }
      if ($variable['update'] || isset($form['#admin'])) {
        $row[] = array(
          'data' => drupal_render($form[$gid]['sa_update']),
        );
      }
      if ($variable['delete'] || isset($form['#admin'])) {
        $row[] = array(
          'data' => drupal_render($form[$gid]['sa_delete']),
        );
      }
      $rows[] = $row;
    }
  }
  if (!empty($rows)) {
    $output .= theme('table', $head, $rows);
    $output .= drupal_render($form);
    return $output;
  }
}
function simple_access_delete_group_confirm() {
  $gid = arg(4);
  $form['gid'] = array(
    '#type' => 'hidden',
    '#value' => $gid,
  );
  return confirm_form($form, t('Are you sure you want to delete this group?'), 'admin/user/simple_access', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
}
function simple_access_delete_group_confirm_submit($form_id, $form_values) {
  simple_access_delete_group($form_values['gid']);
  return 'admin/user/simple_access';
}
function simple_access_page_overview() {
  if (count($groups = simple_access_get_groups())) {
    drupal_set_title(t('Access groups'));
    $roles = user_roles();
    $form['groups'] = array(
      '#tree' => TRUE,
    );
    foreach ($groups as $group) {
      $gid = $group['gid'];
      $form['groups'][$gid]['name'] = array(
        '#value' => $group['name'],
      );
      $r = array();
      foreach ($group['roles'] as $rid) {
        $r[] = $roles[$rid];
      }
      $form['groups'][$gid]['roles'] = array(
        '#value' => implode(', ', $r),
      );
      $form['groups'][$gid]['weight'] = array(
        '#type' => 'weight',
        '#default_value' => $group['weight'],
        '#attributes' => array(
          'class' => 'sa-group-weight',
        ),
      );
      $form['groups'][$gid]['ops'] = array(
        '#value' => l('edit', 'admin/user/simple_access/edit/' . $gid) . '&nbsp;' . l('delete', 'admin/user/simple_access/delete/' . $gid),
      );
    }
    $form['submit'] = array(
      '#type' => 'submit',
      '#value' => t('Update'),
    );
    return $form;
  }
  else {
    drupal_set_message(t('You have not yet defined any access groups.'));
    drupal_goto('admin/user/simple_access/add');
  }
}
function theme_simple_access_page_overview($form) {
  $header = array(
    t('Group'),
    t('Roles'),
    t('Weight'),
    t('Operations'),
  );
  foreach (element_children($form['groups']) as $gid) {
    $rows[] = array(
      'data' => array(
        drupal_render($form['groups'][$gid]['name']),
        array(
          'data' => drupal_render($form['groups'][$gid]['roles']),
          'class' => 'sa-group-roles',
        ),
        drupal_render($form['groups'][$gid]['weight']),
        drupal_render($form['groups'][$gid]['ops']),
      ),
      'class' => 'draggable',
    );
  }
  $output .= theme('table', $header, $rows, array(
    'id' => 'sa-group-list',
  ));
  $output .= drupal_render($form);
  return $output;
}
function simple_access_page_overview_submit($form_id, $form_values) {
  foreach ($form_values['groups'] as $gid => $group) {
    db_query('UPDATE simple_access_groups SET weight = %d WHERE gid = %d', $group['weight'], $gid);
  }
}
function simple_access_profile_list() {
  $form = array();
  $result = db_query('SELECT * FROM {simple_access_profiles} ORDER BY weight ASC, name ASC');
  $form['profiles'] = array(
    '#tree' => TRUE,
  );
  while ($row = db_fetch_array($result)) {
    $form['profiles'][$row['pid']]['name'] = array(
      '#value' => $row['name'],
    );
    $form['profiles'][$row['pid']]['weight'] = array(
      '#type' => 'weight',
      '#default_value' => $row['weight'],
      '#attributes' => array(
        'class' => 'sa-profile-weight',
      ),
    );
    $form['profiles'][$row['pid']]['operations'] = array(
      '#value' => l(t('edit'), 'admin/user/sa_profiles/' . $row['pid'] . '/edit') . ' ' . l(t('delete'), 'admin/user/sa_profiles/' . $row['pid'] . '/delete'),
    );
  }
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Update'),
  );
  return $form;
}
function theme_simple_access_profile_list($form) {
  $head = array(
    t('Name'),
    t('Weight'),
    t('Operations'),
  );
  $rows = array();
  foreach (element_children($form['profiles']) as $id) {
    $rows[] = array(
      'data' => array(
        array(
          'data' => drupal_render($form['profiles'][$id]['name']),
        ),
        array(
          'data' => drupal_render($form['profiles'][$id]['weight']),
        ),
        array(
          'data' => drupal_render($form['profiles'][$id]['operations']),
        ),
      ),
      'class' => 'draggable',
    );
  }
  if (empty($rows)) {
    $rows[] = array(
      array(
        'data' => t('No profiles defined'),
        'colspan' => 3,
        'align' => 'center',
      ),
    );
  }
  $output .= theme('table', $head, $rows, array(
    'id' => 'sa-profile-list',
  ));
  $output .= drupal_render($form);
  return $output;
}
function simple_access_profile_list_submit($form_id, $form_values) {
  foreach ($form_values['profiles'] as $pid => $profile) {
    db_query('UPDATE simple_access_profiles SET weight = %d WHERE pid = %d', $profile['weight'], $pid);
  }
}
function simple_access_profile_form($pid = NULL) {
  $form = array();
  $access_profile = array();
  if (!empty($pid)) {
    $profiles = simple_access_get_profiles();
    if (!isset($profiles[$pid])) {
      drupal_not_found();
      exit;
    }
    $access_profile = $profiles[$pid];
    $form['pid'] = array(
      '#type' => 'value',
      '#value' => $access_profile['pid'],
    );
  }
  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Name'),
    '#default_value' => isset($access_profile['name']) ? $access_profile['name'] : '',
    '#required' => TRUE,
  );
  $form['access'] = array(
    '#tree' => TRUE,
    '#theme' => 'simple_access_form',
  );
  $groups = simple_access_group_select();
  foreach ($groups as $gid => $group) {
    $form['access'][$gid] = simple_access_form_row($gid, $group, $access_profile['access']);
  }
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => empty($pid) ? t('Submit') : t('Update'),
  );
  return $form;
}
function simple_access_profile_form_submit($form_id, $form_values) {
  if (!empty($form_values['pid'])) {
    db_query("UPDATE {simple_access_profiles} SET name = '%s' WHERE pid = %d", $form['pid'], $form['name']);
  }
  else {
    $form_values['pid'] = db_next_id('{simple_access_profiles}_pid');
    db_query("INSERT INTO {simple_access_profiles} (pid, name) VALUES (%d, '%s')", $form_values['pid'], $form_values['name']);
  }
  db_query('DELETE FROM {simple_access_profiles_access} WHERE pid = %d', $form_values['pid']);
  if (isset($form_values['access'])) {
    foreach ($form_values['access'] as $gid => $access) {
      if ($access['sa_view'] || $access['sa_update'] || $access['sa_delete']) {
        db_query("INSERT INTO {simple_access_profiles_access} (pid, gid, sa_view, sa_update, sa_delete) VALUES (%d, %d, %d, %d, %d)", $form_values['pid'], $gid, $access['sa_view'], $access['sa_update'], $access['sa_delete']);
      }
    }
  }
  return 'admin/user/sa_profiles';
}
function simple_access_profile_delete_confirm($pid = NULL) {
  $form['pid'] = array(
    '#type' => 'value',
    '#value' => $pid,
  );
  return confirm_form($form, t('Are you sure you want to delete this profile?'), 'admin/user/sa_profiles', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
}
function simple_access_profile_delete_confirm_submit($form_id, $form_values) {
  simple_access_delete_profile($form_values['pid']);
  return 'admin/user/sa_profiles';
}
function simple_access_settings_page() {
  drupal_set_title(t('Simple Access Settings'));
  $options = array(
    'view' => t('<strong>View</strong>: Displays viewability selections at top of node form. Selected access groups will be the only users who can view the node. All unselected = normal node behavior (viewable by all).<br />'),
    'update' => t('<strong>Edit</strong>: Displays editability selections at top of node form. Users who are part of selected access groups will be able to edit this node. All unselected = "normal" node behavior (only author and admins may edit).<br />'),
    'delete' => t('<strong>Delete</strong>: Displays deleteability selections at top of node form. Users who are part of selected access groups will be able to delete this node. All unselected = "normal" node behavior (only author and admins may delete).<br />'),
  );
  $form['sa_display'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Display'),
    '#default_value' => variable_get('sa_display', array(
      'view',
    )),
    '#options' => $options,
    '#description' => t('Which options should appear on node add/edit pages for administrators? Select at least one.'),
    '#required' => TRUE,
  );
  $form['sa_showgroups'] = array(
    '#type' => 'checkbox',
    '#title' => 'Show groups even when user is not a member.',
    '#default_value' => variable_get('sa_showgroups', 0),
    '#description' => 'This is useful when you want to have a user be able to make content viewable by themselves and a higher privileged group (e.g. students sharing work with faculty)',
  );
  return system_settings_form($form);
}
function simple_access_group_form($gid = NULL) {
  if ($gid) {
    drupal_set_title(t('Edit Access Group'));
    $group = db_fetch_object(db_query('SELECT name, weight FROM {simple_access_groups} WHERE gid = %d', $gid));
    $name = $group->name;
    $weight = $group->weight;
    $roles = simple_access_get_roles($gid);
    $form['gid'] = array(
      '#type' => 'hidden',
      '#value' => $gid,
    );
  }
  else {
    drupal_set_title(t('Create Access Group'));
    $weight = 0;
  }
  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Name'),
    '#default_value' => $name,
    '#size' => 40,
    '#maxlength' => 80,
    '#description' => t('The name for the access group as it will appear on the content editing form.'),
    '#attributes' => $attributes = NULL,
    '#required' => TRUE,
  );
  $form['roles'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Roles'),
    '#default_value' => $roles,
    '#options' => user_roles(),
    '#description' => t('Roles that can view'),
  );
  $form['weight'] = array(
    '#type' => 'weight',
    '#title' => 'Weight',
    '#default_value' => $weight,
    '#delta' => 10,
    '#description' => t('When setting permissions, heavier names will sink and lighter names will be positioned nearer the top.'),
  );
  $form[] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );
  return $form;
}
function simple_access_group_form_submit($form_id, $form_values) {
  simple_access_save_group($form_values);
  return 'admin/user/simple_access';
}
function simple_access_get_roles($gid) {
  $roles = array();
  $sql = db_query('SELECT rid FROM {simple_access_roles} WHERE gid = %d', $gid);
  while ($row = db_fetch_object($sql)) {
    $roles[] = $row->rid;
  }
  return $roles;
}
function simple_access_get_profiles_select() {
  $profiles = simple_access_get_profiles();
  return array_map('_simple_access_filter_profiles', $profiles);
}
function _simple_access_filter_profiles($a) {
  return $a['name'];
}
function simple_access_get_profiles() {
  $profiles = array();
  $result = db_query('SELECT pid, name FROM {simple_access_profiles} ORDER BY weight, name');
  while ($p = db_fetch_array($result)) {
    $profiles[$p['pid']] = $p;
    $profiles[$p['pid']]['access'] = array();
  }
  $result = db_query('SELECT pid, gid, sa_view, sa_update, sa_delete FROM {simple_access_profiles_access} ORDER BY pid');
  while ($a = db_fetch_array($result)) {
    if (isset($profiles[$a['pid']])) {
      $profiles[$a['pid']]['access'][$a['gid']] = array(
        'sa_view' => $a['sa_view'],
        'sa_update' => $a['sa_update'],
        'sa_delete' => $a['sa_delete'],
      );
    }
  }
  return $profiles;
}
function simple_access_get_groups() {
  $groups = array();
  $result = db_query('SELECT gid, name, weight FROM {simple_access_groups} ORDER BY weight, name');
  while ($g = db_fetch_array($result)) {
    $groups[$g['gid']]['name'] = $g['name'];
    $groups[$g['gid']]['gid'] = $g['gid'];
    $groups[$g['gid']]['weight'] = $g['weight'];
    $groups[$g['gid']]['roles'] = simple_access_get_roles($g['gid']);
  }
  return $groups;
}
function simple_access_group_select() {
  static $groups;
  if (empty($groups)) {
    global $user;
    $default_access = user_access('administer nodes');
    $groups = array();
    $result = db_query('SELECT gid, name FROM {simple_access_groups} ORDER BY weight, name');
    while ($group = db_fetch_array($result)) {
      $groups[$group['gid']] = $group;
      $groups[$group['gid']]['access'] = $default_access;
    }
    if (!$default_access) {

      // return just groups for which user is a member
      $roles = array_keys($user->roles);
      $result = db_query('SELECT DISTINCT g.gid FROM {simple_access_groups} g INNER JOIN {simple_access_roles} r ON g.gid = r.gid WHERE r.rid IN (' . implode(',', array_fill(0, count($roles), '%d')) . ') ORDER BY weight, name', $roles);
      while ($group = db_fetch_array($result)) {
        $groups[$group['gid']]['access'] = TRUE;
      }
    }
  }
  return $groups;
}

/**
 * Get a list of group/grant ids based on a list of user roles
 * $roles should be a linear list a role ids
 */
function simple_access_groups_from_roles($roles) {

  // there probably should be some 'static' stuff going on here
  // always return gid 0 just to be safe.
  $gids = array(
    0,
  );
  $result = db_query('SELECT gid FROM {simple_access_roles} WHERE rid IN (' . implode(',', array_fill(0, count($roles), '%d')) . ')', $roles);
  while ($g = db_fetch_object($result)) {
    $gids[] = $g->gid;
  }
  return $gids;
}

/**
 * Save group of roles into the database
 * $roles is an associative array of roles where the keys are role ids
 * $name is the name of the group
 * $gid is the group id
 *
 */
function simple_access_save_group($edit) {
  if (!$edit['gid']) {
    $edit['gid'] = db_next_id('{simple_access_groups}_gid');
  }
  db_query('DELETE FROM {simple_access_roles} WHERE gid = %d', $edit['gid']);
  db_query('DELETE FROM {simple_access_groups} WHERE gid = %d', $edit['gid']);
  $success = db_query("INSERT INTO {simple_access_groups} (gid, name, weight) VALUES (%d, '%s', %d)", $edit['gid'], $edit['name'], $edit['weight']);
  if (is_array($edit['roles'])) {
    foreach ($edit['roles'] as $key => $value) {
      if ($value) {
        $success = $success && db_query('INSERT INTO {simple_access_roles} (rid, gid) VALUES (%d, %d)', $key, $edit['gid']);
      }
    }
  }
  if (!$success) {
    drupal_set_message(t('There was a problem saving to the database.'));
  }
  return $success;
}
function simple_access_delete_profile($pid) {
  db_query('DELETE FROM {simple_access_profiles} WHERE pid = %d', $pid);
  db_query('DELETE FROM {simple_access_profiles_access} WHERE pid = %d', $pid);
  db_query('DELETE FROM {simple_access_profiles_node} WHERE pid = %d', $pid);
}
function simple_access_delete_group($gid) {
  db_query('DELETE FROM {simple_access_roles} WHERE gid = %d', $gid);
  db_query('DELETE FROM {simple_access_groups} WHERE gid = %d', $gid);
  db_query('DELETE FROM {simple_access_node} WHERE gid = %d', $gid);
}

/**
 * List hidden, editable, and deletable nodes
 */
function simple_access_nodes() {
  switch (arg(3)) {
    case 'edit':
      drupal_set_title(t('Items With Edit Access Set'));
      $output = '<div>' . t('These nodes have been set as "additionally editable by" certain Simple Access <a href="!url">groups</a>. ', array(
        '!url' => url('admin/user/simple_access'),
      )) . '</div><br />';
      $sql = "SELECT DISTINCT n.title, na.nid FROM {node} n INNER JOIN {node_access} na ON n.nid = na.nid WHERE na.realm='simple_access' AND na.gid > 0 AND na.grant_update = 1";
      break;
    case 'delete':
      drupal_set_title(t('Items With Delete Access Set'));
      $output = '<div>' . t('These nodes have been set as "additionally deletable by" certain Simple Access <a href="!url">groups</a>. ', array(
        '!url' => url('admin/user/simple_access'),
      )) . '</div><br />';
      $sql = "SELECT DISTINCT n.title, na.nid FROM {node} n INNER JOIN {node_access} na ON n.nid = na.nid WHERE na.realm='simple_access' AND na.gid > 0 AND na.grant_delete = 1";
      break;
    case 'view':
    default:
      drupal_set_title(t('Items With View Access Set'));
      $output = '<div>' . t('These nodes have been set as "only viewable by" certain Simple Access <a href="!url">groups</a>.', array(
        '!url' => url('admin/user/simple_access'),
      )) . '</div><br />';
      $sql = "SELECT DISTINCT n.title, na.nid FROM {node} n INNER JOIN {node_access} na ON n.nid = na.nid WHERE na.realm='simple_access' AND na.gid > 0 AND na.grant_view = 1";
      break;
  }
  $header = array(
    array(
      'data' => t('ID'),
      'field' => 'n.nid',
      'sort' => 'desc',
    ),
    array(
      'data' => t('Title'),
      'field' => 'n.title',
    ),
    array(
      'data' => '&nbsp;',
    ),
  );
  $sql .= tablesort_sql($header);
  $result = pager_query($sql, 50);
  $groups_info = simple_access_get_groups();
  while ($r = db_fetch_object($result)) {
    $groups = array();
    $rs2 = db_query('SELECT na.gid, na.grant_view, na.grant_update, na.grant_delete FROM {node_access} na WHERE na.nid = %d AND na.realm = \'simple_access\'', $r->nid);
    while ($r2 = db_fetch_object($rs2)) {
      $groups[] = $groups_info[$r2->gid]['name'];
    }
    $rows[$r->nid]['nid'] = array(
      'data' => $r->nid,
      'style' => 'vertical-align:top',
    );
    $info = '<div>' . $r->title . '</div><div style="font-size:xx-small">' . implode(', ', $groups) . '</div>';
    $rows[$r->nid]['title'] = array(
      'data' => $info,
      'style' => 'vertical-align:top',
    );
    $rows[$r->nid]['ops'] = array(
      'data' => l(t('view'), 'node/' . $r->nid) . ' ' . l(t('edit'), 'node/' . $r->nid . '/edit', array(), drupal_get_destination()),
      'style' => 'vertical-align:top',
    );
  }
  if ($rows) {
    $output .= theme('table', $header, $rows, array(
      'style' => 'width:100%',
    ));
    $output .= theme('pager', array(), 50);
  }
  else {
    $output .= '<div>' . t('No nodes match this criteria.') . '</div>';
  }
  return $output;
}

/**
 * Filter the access records for the corrent user
 */
function _simple_access_filter_access($a) {
  $groups = simple_access_group_select();
  return isset($groups[$a['gid']]['access']) && $groups[$a['gid']]['access'];
}

Functions

Namesort descending Description
simple_access_delete_group
simple_access_delete_group_confirm
simple_access_delete_group_confirm_submit
simple_access_delete_profile
simple_access_form
simple_access_form_alter
simple_access_form_row
simple_access_get_groups
simple_access_get_profiles
simple_access_get_profiles_select
simple_access_get_roles
simple_access_groups_from_roles Get a list of group/grant ids based on a list of user roles $roles should be a linear list a role ids
simple_access_group_form
simple_access_group_form_submit
simple_access_group_select
simple_access_menu Implementation of hook_menu().
simple_access_nodeapi Implementation of hook_nodeapi()
simple_access_nodes List hidden, editable, and deletable nodes
simple_access_node_access_explain Implementation of hook_node_access_explain()
simple_access_node_access_records Implementation of hook_node_access_records
simple_access_node_grants Implementation of hook_node_grants().
simple_access_page_overview
simple_access_page_overview_submit
simple_access_perm Implementation of hook_perm().
simple_access_profile_delete_confirm
simple_access_profile_delete_confirm_submit
simple_access_profile_form
simple_access_profile_form_submit
simple_access_profile_list
simple_access_profile_list_submit
simple_access_save_group Save group of roles into the database $roles is an associative array of roles where the keys are role ids $name is the name of the group $gid is the group id
simple_access_settings_page
theme_simple_access_form
theme_simple_access_page_overview
theme_simple_access_profile_list
_simple_access_filter_access Filter the access records for the corrent user
_simple_access_filter_profiles