You are here

vppn.module in View Permission Per Node 7

Configuration for VPPN.

File

vppn.module
View source
<?php

/**
 * @file
 * Configuration for VPPN.
 */

/**
 * Implements hook_menu().
 */
function vppn_menu() {

  // The menu item configurations.
  $items = array();

  // The admin settings form.
  $items['admin/config/content/vppn'] = array(
    'title' => 'View Permission Per Node settings',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'vppn_config_form',
    ),
    'access arguments' => array(
      'administer vppn',
    ),
    'file' => 'vppn.admin.inc',
  );

  // Return the new menu items.
  return $items;
}

/**
 * Implements hook_permission().
 */
function vppn_permission() {

  // Return the permission definitions.
  return array(
    // Use VPPN.
    'use vppn' => array(
      'title' => t('Use VPPN'),
      'description' => t('View the VPPN settings on a node form'),
    ),
    // Administration VPPN.
    'administer vppn' => array(
      'title' => t('Administer VPPN'),
      'description' => t('Perform administration tasks for Views Permission Per Node.'),
    ),
  );
}

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function vppn_form_node_form_alter(&$form) {

  // Make sure it's a valid type.
  if (empty($form['type']['#value']) || !variable_get('vppn_node_' . $form['type']['#value'], 0)) {

    // Not a VPPN form.
    return;
  }

  // VPPN vertical tab settings.
  $form['vppn'] = array(
    '#type' => 'fieldset',
    '#access' => user_access('use vppn'),
    '#title' => t('View Access'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    // Make it a vtab.
    '#group' => 'additional_settings',
    '#attributes' => array(
      'class' => array(
        'node-form-vppn',
      ),
    ),
    // Put just below publishing options et al.
    '#weight' => !empty($form['options']['#weight']) ? $form['options']['#weight'] + 1 : 96,
  );

  // Add a description.
  $form['vppn']['description'] = array(
    // Consistent spacing is nice.
    '#prefix' => '<div class="form-item">',
    '#suffix' => '</div>',
    '#markup' => t('Select which roles can view this node.  Select none for default.'),
  );

  // Get the default roles.
  $default_roles = _vppn_get_node_defaults($form['#node']);
  $default_roles = $default_roles ? $default_roles : array();

  // Role checkboxes.
  $form['vppn']['vppn_roles'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Select roles'),
    '#title_display' => 'invisible',
    '#options' => array(),
    '#default_value' => $default_roles,
  );

  // Get all user roles.
  $user_roles = user_roles();

  // Get users that can bypass access control (skip anon - that would be weird).
  $user_roles_bypass = user_roles(TRUE, 'bypass node access');

  // Remove the users that can bypass access control.
  $user_roles = array_diff_key($user_roles, $user_roles_bypass);

  // Each non-bypass role.
  foreach ($user_roles as $role_id => $role_name) {
    $form['vppn']['vppn_roles']['#options'][$role_id] = $role_name;
  }

  // Add submission handler.
  $form['actions']['submit']['#submit'][] = 'vppn_node_form_submit';
}

/**
 * Submission for the node form that has VPPN enabled.
 */
function vppn_node_form_submit(&$form, &$form_state) {

  // Bail out if no nid.
  if (empty($form_state['nid'])) {
    return;
  }

  // Bail out if no roles.
  if (empty($form_state['values']['vppn_roles'])) {
    return;
  }

  // Get the defaults.
  $defaults = $form['vppn']['vppn_roles']['#default_value'];

  // Each role.
  foreach ($form_state['values']['vppn_roles'] as $role_id => $value) {

    // Check if there was a default.
    $exists = in_array($role_id, $defaults);

    // Check if there was no change.
    if (!$exists && $value === 0 || $exists && $value !== 0) {

      // Bail out if no change.
      continue;
    }

    // Delete the record if it was changed & removed.
    if ($value === 0) {

      // Remove the role from the viewable roles.
      db_delete('vppn')
        ->condition('nid', $form_state['nid'])
        ->condition('rid', $role_id)
        ->execute();
    }
    else {

      // Add the role to the viewable roles.
      db_insert('vppn')
        ->fields(array(
        'nid' => $form_state['nid'],
        'rid' => $value,
      ))
        ->execute();
    }
  }
}

/**
 * Implements hook_node_access().
 */
function vppn_node_access($node, $op, $account) {

  // Only concerned with viewing.
  if ($op != 'view') {

    // Ignore if any other op.
    return NODE_ACCESS_IGNORE;
  }

  // Make sure there's a node id.
  if (empty($node->nid)) {

    // Should never happen but ignore if no nid.
    return NODE_ACCESS_IGNORE;
  }

  // Check if it's a valid VPPN content type.
  if (empty($node->type) || !variable_get('vppn_node_' . $node->type, 0)) {

    // Not a VPPN node type, we don't care.
    return NODE_ACCESS_IGNORE;
  }

  // Get the records for this node.
  $records = db_select('vppn')
    ->fields('vppn', array(
    'rid',
  ))
    ->condition('nid', $node->nid)
    ->execute();

  // Check that there is a record for this node.
  if (!$records
    ->rowCount()) {

    // No record.
    return NODE_ACCESS_IGNORE;
  }

  // Get the roles that can view this node.
  $allowed_roles = array_flip($records
    ->fetchCol());

  // Make sure the user has one of the allowed roles.
  return count(array_intersect_key($allowed_roles, $account->roles)) ? NODE_ACCESS_ALLOW : NODE_ACCESS_DENY;
}

/**
 * Helper function to get the default VPPN permissions for a node.
 */
function _vppn_get_node_defaults($node) {

  // Chekc if this node is not yet defined.
  if (empty($node->nid)) {

    // Not defined, so return empty array.
    return array();
  }

  // Return the an array of nodes that can view this node.
  return db_select('vppn')
    ->fields('vppn')
    ->condition('nid', $node->nid)
    ->execute()
    ->fetchCol(1);
}

Functions

Namesort descending Description
vppn_form_node_form_alter Implements hook_form_BASE_FORM_ID_alter().
vppn_menu Implements hook_menu().
vppn_node_access Implements hook_node_access().
vppn_node_form_submit Submission for the node form that has VPPN enabled.
vppn_permission Implements hook_permission().
_vppn_get_node_defaults Helper function to get the default VPPN permissions for a node.