You are here

ack_node.module in Access Control Kit 7

The ACK node module.

File

ack_node/ack_node.module
View source
<?php

/**
 * @file
 * The ACK node module.
 */

/**
 * Implements hook_access_info().
 */
function ack_node_access_info() {

  // Declare support for controlling access to nodes.
  $info['node'] = array(
    'label' => t('Content'),
  );
  return $info;
}

/**
 * Implements hook_access_handler_info().
 */
function ack_node_access_handler_info() {

  // Handlers for node properties.
  $info['ACKNodeAuthor'] = array(
    'label' => t('Author'),
    'scheme types' => array(
      'user',
    ),
    'object types' => array(
      'node',
    ),
  );
  $info['ACKNodeSticky'] = array(
    'label' => t('Sticky'),
    'scheme types' => array(
      'boolean',
    ),
    'object types' => array(
      'node',
    ),
  );

  // Handler for the taxonomy index.
  if (module_exists('taxonomy')) {
    $info['ACKNodeTaxonomyIndex'] = array(
      'label' => t('Term association'),
      'scheme types' => array(
        'taxonomy_term',
      ),
      'object types' => array(
        'node',
      ),
    );
  }
  return $info;
}

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

  // Create ACK-enabled create/edit/delete permissions for each content type.
  $perms = array();
  $scheme_names = access_object_schemes('node', TRUE);
  $t_args = array(
    '%schemes' => implode(', ', $scheme_names),
  );
  foreach (node_permissions_get_configured_types() as $type) {
    $type_info = node_type_get_type($type);
    $t_args['%type'] = $type_info->name;
    $perms += array(
      "ack create {$type} content" => array(
        'title' => t('%type: Create new content in assigned access realms', $t_args),
        'description' => t('This permission only applies to the following access schemes: %schemes.', $t_args),
      ),
      "ack edit own {$type} content" => array(
        'title' => t('%type: Edit own content in assigned access realms', $t_args),
        'description' => t('This permission only applies to the following access schemes: %schemes.', $t_args),
      ),
      "ack edit any {$type} content" => array(
        'title' => t('%type: Edit any content in assigned access realms', $t_args),
        'description' => t('This permission only applies to the following access schemes: %schemes.', $t_args),
      ),
      "ack delete own {$type} content" => array(
        'title' => t('%type: Delete own content in assigned access realms', $t_args),
        'description' => t('This permission only applies to the following access schemes: %schemes.', $t_args),
      ),
      "ack delete any {$type} content" => array(
        'title' => t('%type: Delete any content in assigned access realms', $t_args),
        'description' => t('This permission only applies to the following access schemes: %schemes.', $t_args),
      ),
    );
  }
  return $perms;
}

/**
 * Implements hook_node_access().
 */
function ack_node_node_access($node, $op, $account) {
  $type = is_string($node) ? $node : $node->type;
  if (in_array($type, node_permissions_get_configured_types())) {
    if ($op == 'create' && user_access('ack create ' . $type . ' content', $account)) {

      // The user must have the permission in at least one realm, in any scheme,
      // in order to exercise that permission to create a node.
      foreach (access_user_permission_realms('ack create ' . $type . ' content', $account) as $realms) {
        if (!empty($realms)) {
          return NODE_ACCESS_ALLOW;
        }
      }
    }
    if ($op == 'update') {
      if (access_user_object_access('ack edit any ' . $type . ' content', 'node', $node, $account) || access_user_object_access('ack edit own ' . $type . ' content', 'node', $node, $account) && $account->uid == $node->uid) {
        return NODE_ACCESS_ALLOW;
      }
    }
    if ($op == 'delete') {
      if (access_user_object_access('ack delete any ' . $type . ' content', 'node', $node, $account) || access_user_object_access('ack delete own ' . $type . ' content', 'node', $node, $account) && $account->uid == $node->uid) {
        return NODE_ACCESS_ALLOW;
      }
    }
  }

  // Returning nothing from this function would have the same effect.
  return NODE_ACCESS_IGNORE;
}

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 *
 * Alters the node form to filter the options on ACK-related elements.
 */
function ack_node_form_node_form_alter(&$form, &$form_state, $form_id) {
  global $user;

  // Don't filter anything if the user can bypass access controls.
  if (user_access('bypass node access')) {
    return;
  }
  $node = $form_state['node'];
  $schemes = access_object_schemes('node');

  // Only filter the create form if the user lacks global create permission.
  if (empty($node->nid) && !user_access('create ' . $node->type . ' content')) {

    // Get the list of realms in which the user can create this type of node.
    $realms = access_user_permission_realms('ack create ' . $node->type . ' content', $user, $schemes);
    _ack_node_form_node_form_alter($form, $form_state, $form_id, $schemes, $realms);
  }
  elseif (!empty($node->nid) && !(user_access('edit any ' . $node->type . ' content') || user_access('edit own ' . $node->type . ' content') && $user->uid == $node->uid)) {
    _ack_node_form_node_form_alter($form, $form_state, $form_id, $schemes);
  }
}

/**
 * Helper function for ack_node_form_node_form_alter().
 *
 * Applies AccessControlKitHandlerInterface::objectFormAlter() to the node form
 * for all applicable handlers.
 *
 * @param array &$form
 *   The node form.
 * @param array &$form_state
 *   The current form state.
 * @param string $form_id
 *   The form ID.
 * @param array $schemes
 *   An array of access schemes.
 * @param array $realms
 *   (optional) An array, indexed by scheme machine name, where the values are
 *   arrays of realm values. Defaults to NULL.
 */
function _ack_node_form_node_form_alter(&$form, &$form_state, $form_id, $schemes, $realms = NULL) {
  $node = $form_state['node'];
  foreach ($schemes as $scheme) {
    $scheme_realms = !empty($realms) ? $realms[$scheme->machine_name] : NULL;
    $scheme->handlers['node']
      ->objectFormAlter('node', $node, $form, $form_state, $form_id, $scheme_realms);
  }
}