node_access_link.module 6.3 KB
Newer Older
Bobík's avatar
Bobík committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
<?php
// $Id$

/**
 * @file
 * TODO: Enter file description here.
 */

/**
 * Alter of node_type_form.
 */
function node_access_link_form_node_type_form_alter(&$form, &$form_state) {
  $form['node_access_link'] = array(
    '#type' => 'fieldset',
    '#title' => t('Node Auth Key'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#group' => 'additional_settings',
  );
  
  $instance = field_info_instance('node', 'field_node_access_link_authkey', $form['#node_type']->type);
  
  $form['node_access_link']['node_access_link_enable'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable'),
    '#default_value' => (bool)$instance,
    '#description' => t('Disable of this feature will cost erase of authorization keys of all nodes in this node type.'),
  );
  
  if(is_array($instance) && isset($instance['node_access_link_grants']))
    $default_grants = array_keys($instance['node_access_link_grants'], TRUE);
  else
    $default_grants = array();
  
  $form['node_access_link']['node_access_link_grants'] = array(
    '#type' => 'checkboxes', 
Bobík's avatar
Bobík committed
37
    '#title' => t('Grants to give'), 
Bobík's avatar
Bobík committed
38 39 40 41 42 43
    '#default_value' => $default_grants,
    '#options' => array(
      'view' => t('View'),
      'update' => t('Update'), 
      'delete' => t('Delete'), 
    ),
Bobík's avatar
Bobík committed
44
    '#description' => t('What operations will be temporarily given to authorised user for the node. This not affect users who is authorised yet.'),
Bobík's avatar
Bobík committed
45 46 47 48 49 50 51 52 53 54 55
  );
  
  $form['#submit'][] = 'node_access_link_form_node_type_form_alter_submit';
}

/**
 * Submit for node_type_form.
 */
function node_access_link_form_node_type_form_alter_submit(&$form, &$form_state) {
  $instance = field_info_instance('node', 'field_node_access_link_authkey', $form_state['values']['type']);
  
Bobík's avatar
Bobík committed
56 57 58
  // Instance does not exist and checkbox is enabled - create filed and instance
  if(!$instance && $form_state['values']['node_access_link_enable']) {
    node_access_link_create_field_instance($form_state['values']['type'], $form_state['values']['node_access_link_grants']);
Bobík's avatar
Bobík committed
59 60
  }
  
Bobík's avatar
Bobík committed
61 62 63 64 65 66 67 68
  // Instance exists and checkbox is enabled - update instance
  elseif($instance && $form_state['values']['node_access_link_enable']) {
    $instance['node_access_link_grants'] = $form_state['values']['node_access_link_grants'];
    field_update_instance($instance);
  }
  
  // Instance exists and checkbox is disabled - delete filed and instance
  elseif($instance && !$form_state['values']['node_access_link_enable']) {
Bobík's avatar
Bobík committed
69 70 71 72 73 74 75 76 77
    field_delete_instance($instance);
  }
  
  
}

/**
 * Create field instance in specified node type.
 */
Bobík's avatar
Bobík committed
78
function node_access_link_create_field_instance($node_type, $grants) {
Bobík's avatar
Bobík committed
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
  if(!field_info_field('field_node_access_link_authkey')) {
    $field = array(
      'translatable' => '1',
      'settings' => array(
        'code' => '',
        'display_format' => '$display_output = $entity_field_item[\'value\'];',
        'store' => 1,
        'database' => array(
          'data_type' => 'varchar',
          'data_length' => '64',
          'data_size' => 'normal',
          'data_precision' => '10',
          'data_scale' => '2',
          'data_default' => '',
          'data_not_NULL' => 1,
          'data_index' => 0,
        ),
      ),
      'field_name' => 'field_node_access_link_authkey',
      'type' => 'computed',
      'active' => '1',
      'locked' => '0',
      'cardinality' => '1',
    );
    field_create_field($field);
  }
  
  $instance = array(
    'label' => 'Node access link',
    'widget' => array(
      'type' => 'computed',
      'weight' => '1',
      'settings' => array(),
    ),
    'settings' => array(
      'user_register_form' => FALSE,
    ),
    'display' => array(
      'default' => array(
        'label' => 'above',
        'type' => 'hidden',
        'weight' => '12',
        'settings' => array(),
      ),
      'teaser' => array(
        'type' => 'hidden',
        'label' => 'above',
        'settings' => array(),
        'weight' => 0,
      ),
    ),
    'required' => FALSE,
    'description' => '',
    'field_name' => 'field_node_access_link_authkey',
    'entity_type' => 'node',
    'bundle' => $node_type,
Bobík's avatar
Bobík committed
135
    'node_access_link_grants' => $grants,
Bobík's avatar
Bobík committed
136 137 138 139 140 141 142 143 144 145 146 147
  );
  field_create_instance($instance);
}

/**
 * Implementation of hook_node_access().
 */
function node_access_link_node_access($node, $op, $account) {
  // Ignore if just creating node
  if($op == 'create')
    return NODE_ACCESS_IGNORE;
  
Bobík's avatar
Bobík committed
148 149 150 151 152
  // Check key if:
  if(isset($_GET['authkey']) && // authkey param is set
     isset($node->field_node_access_link_authkey) && // authkey in node is set
     !isset($_SESSION['node_access_link_auth_nodes'][$node->nid])) { // grants has not loaded yet
    
Bobík's avatar
Bobík committed
153 154 155 156 157
    $authkeys = field_get_items('node', $node, 'field_node_access_link_authkey');
    if($authkeys[0]['value'] == $_GET['authkey']) {
      // Start session
      if(!isset($_SESSION))
        drupal_session_initialize();
Bobík's avatar
Bobík committed
158 159 160 161
      
      // Load settings
      $instance = field_info_instance('node', 'field_node_access_link_authkey', $node->type);
      
Bobík's avatar
Bobík committed
162
      // Save authorization to session
Bobík's avatar
Bobík committed
163
      $_SESSION['node_access_link_auth_nodes'][$node->nid] = $instance['node_access_link_grants'];
Bobík's avatar
Bobík committed
164 165 166 167
    }
  }
  
  // Permit if checked
Bobík's avatar
Bobík committed
168 169
  if(isset($_SESSION['node_access_link_auth_nodes'][$node->nid]) &&
     $_SESSION['node_access_link_auth_nodes'][$node->nid][$op])
Bobík's avatar
Bobík committed
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
    return NODE_ACCESS_ALLOW;
}

/**
 * Computed field callback which generate auth key.
 */
function computed_field_field_node_access_link_authkey_compute(&$entity_field, $entity_type, $entity, $field, $instance, $langcode, $items) {
  
  // Break if set yet and entity is not node
  if(!empty($entity_field[0]['value']) || $entity_type != 'node')
    return;
  
  // Find key in other languages
  foreach($entity->field_node_access_link_authkey as $values) {
    if(!empty($values[0]['value'])) {
      $actual = $values[0]['value'];
      break;
    }
  }
  
  // Generate new key
  if(!isset($actual))
    $actual = hash('sha256', drupal_random_bytes(64));
  
  $entity_field[0]['value'] = $actual;
}

/**
 * Get edit URL of specified node.
 * @param $node Node object or NID.
 */
function node_access_link_get_url($node) {
  if(is_numeric($node))
    $node = node_load($node);
    
  $items = field_get_items('node', $node, 'field_node_access_link_authkey');
  if(!$items)
    return FALSE;
  
  return url("node/$node->nid/edit", array(
    'absolute' => TRUE,
    'query' => array('authkey' => $items[0]['value']),
  ));
}