You are here

node_authlink.module in Node authorize link 7

Same filename and directory in other branches
  1. 8 node_authlink.module

Provides functionality for the node_authlink module.

File

node_authlink.module
View source
<?php

/**
 * @file
 * Provides functionality for the node_authlink module.
 */

/**
 * Implements hook_form_node_type_form_alter().
 */
function node_authlink_form_node_type_form_alter(&$form, &$form_state) {
  $form['node_authlink'] = array(
    '#type' => 'fieldset',
    '#title' => t('Node authorize link'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#group' => 'additional_settings',
  );
  $form['node_authlink']['node_authlink_enable'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable'),
    '#default_value' => variable_get('node_authlink_enable_' . $form['#node_type']->type, FALSE),
    '#description' => t('Disable of this feature will cost erase of authorization keys of all nodes in this node type.'),
  );
  $form['node_authlink']['node_authlink_grants'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Grants to give'),
    '#default_value' => variable_get('node_authlink_grants_' . $form['#node_type']->type, array()),
    '#options' => array(
      'view' => t('View'),
      'update' => t('Update'),
      'delete' => t('Delete'),
    ),
    '#description' => t('What operations will be temporarily given to authorised user for the node. This not affect users who is authorised yet.'),
  );

  // Time periods: none, 1 day, 1 week, 4 weeks, 3 months, 6 months, 1 year.
  $period = drupal_map_assoc(array(
    0,
    86400,
    604800,
    2419200,
    7776000,
    15552000,
    31536000,
  ), 'format_interval');
  $period[0] = '<' . t('disabled') . '>';
  $form['node_authlink']['node_authlink_expire'] = array(
    '#type' => 'select',
    '#title' => t('Regenerate authkeys after'),
    '#default_value' => variable_get('node_authlink_expire_' . $form['#node_type']->type, 0),
    '#options' => $period,
    '#description' => t('Keys older than selected time will be regenerated by cron run.'),
  );
  $form['node_authlink']['node_authlink_batch'] = array(
    '#type' => 'fieldset',
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
    '#title' => t('Batch operations'),
    '#description' => t('Affects all nodes in this node type.'),
  );
  $form['node_authlink']['node_authlink_batch']['generate'] = array(
    '#type' => 'submit',
    '#value' => t('Generate authkeys'),
    '#submit' => array(
      'node_authlink_batch_generate',
    ),
  );
  $form['node_authlink']['node_authlink_batch']['delete'] = array(
    '#type' => 'submit',
    '#value' => t('Delete all authkeys'),
    '#submit' => array(
      'node_authlink_batch_delete',
    ),
  );
  $form['#submit'][] = 'node_authlink_form_node_type_form_alter_submit';
}

/**
 * Callback: Submit for node_type_form.
 */
function node_authlink_form_node_type_form_alter_submit(&$form, &$form_state) {

  // Disabled.
  if (!$form_state['values']['node_authlink_enable']) {
    variable_del('node_authlink_enable_' . $form_state['values']['type']);
    variable_del('node_authlink_grants_' . $form_state['values']['type']);
  }
}

/**
 * Callback: Generate authkeys for all nodes in node type.
 */
function node_authlink_batch_generate(&$form, &$form_state) {

  // Load NIDs that are not in the authkeys table.
  $query = db_select('node', 'n');
  $query
    ->leftJoin('node_authlink_nodes', 'a', 'n.nid = a.nid');
  $query
    ->fields('n', array(
    'nid',
  ))
    ->condition('type', $form_state['values']['type'])
    ->isNull('authkey');
  $nids = $query
    ->execute()
    ->fetchCol();

  // Create keys.
  foreach ($nids as $nid) {
    node_authlink_node_insert($nid);
    if (module_exists('entitycache')) {
      cache_clear_all($nid, 'cache_entity_node');
    }
  }
  drupal_set_message(t('%num authkeys has been generated.', array(
    '%num' => count($nids),
  )));
}

/**
 * Callback: Delete authkeys for all nodes in node type.
 */
function node_authlink_batch_delete(&$form, &$form_state) {

  // NIDs of nodes that are in this node type.
  $query = db_select('node', 'n');
  $query
    ->leftJoin('node_authlink_nodes', 'a', 'n.nid = a.nid');
  $query
    ->fields('n', array(
    'nid',
  ))
    ->condition('type', $form_state['values']['type'])
    ->isNotNull('authkey');
  $nids = $query
    ->execute()
    ->fetchCol();

  // Delete keys.
  $count = db_delete('node_authlink_nodes')
    ->condition('nid', $nids, 'IN')
    ->execute();
  foreach ($nids as $nid) {
    if (module_exists('entitycache')) {
      cache_clear_all($nid, 'cache_entity_node');
    }
  }
  drupal_set_message(t('%num authkeys has been deleted.', array(
    '%num' => $count,
  )));
}

/**
 * Implements hook_node_load().
 *
 * Appends authkey to loaded node object.
 */
function node_authlink_node_load($nodes, $types) {
  foreach ($nodes as $nid => $node) {

    // TODO: check node type (performance)
    if ($authkey = node_authlink_load_authkey($nid)) {
      $nodes[$nid]->authkey = $authkey;
    }
  }
}

/**
 * Loads key from NID.
 *
 * @param string $nid
 *   The node id.
 *
 * @return string
 *   The authkey.
 */
function node_authlink_load_authkey($nid) {
  $result = db_query('SELECT authkey FROM {node_authlink_nodes} WHERE nid = :nid', array(
    ':nid' => $nid,
  ));
  return $result
    ->fetchField();
}

/**
 * Get edit URL of specified node.
 *
 * @param int|object $node
 *   Node object or NID.
 * @param string $op
 *   Operation to do with node. view, edit (default) or delete.
 *
 * @return string
 *   The node operation's URL with authkey query appended.
 */
function node_authlink_get_url($node, $op = 'edit') {
  if (is_numeric($node)) {
    $node = node_load($node);
  }
  if (!isset($node->authkey)) {
    return FALSE;
  }
  if ($op == 'view') {
    $op = '';
  }
  else {
    $op = '/' . $op;
  }
  return url("node/{$node->nid}{$op}", array(
    'absolute' => TRUE,
    'query' => array(
      'authkey' => $node->authkey,
    ),
  ));
}

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

  // Ignore if just creating node.
  if ($op == 'create') {
    return NODE_ACCESS_IGNORE;
  }

  // Ignore if node type is not enabled.
  if (!variable_get('node_authlink_enable_' . $node->type, FALSE)) {
    return NODE_ACCESS_IGNORE;
  }

  // Check key if:
  // authkey param is set and in node is set.
  if (isset($_GET['authkey']) && isset($node->authkey)) {
    if ($node->authkey == $_GET['authkey']) {

      // Start session.
      if (!isset($_SESSION)) {
        drupal_session_initialize();
      }

      // Save allowed grants to session.
      $_SESSION['node_authlink_nodes'][$node->nid] = variable_get('node_authlink_grants_' . $node->type, array());
    }
  }

  // Permit if checked.
  if (isset($_SESSION['node_authlink_nodes'][$node->nid]) && in_array($op, $_SESSION['node_authlink_nodes'][$node->nid])) {
    return NODE_ACCESS_ALLOW;
  }
}

/**
 * Implements hook_node_presave().
 *
 * Pre-generate auth key for the new node (e.g. for use in Rules).
 */
function node_authlink_node_presave($node) {

  // Ignore if node type is disabled.
  if (!variable_get('node_authlink_enable_' . $node->type, FALSE)) {
    return;
  }

  // Generate key.
  if (!isset($node->authkey)) {
    $node->authkey = hash('sha256', drupal_random_bytes(64));
  }
}

/**
 * Implements hook_node_insert().
 *
 * Generate and save auth key for the new node.
 */
function node_authlink_node_insert($node) {

  // Allow key generate without load node object.
  if (is_numeric($node)) {
    $nid = $node;
  }
  else {
    $nid = $node->nid;

    // Ignore if node type is disabled.
    if (!variable_get('node_authlink_enable_' . $node->type, FALSE)) {
      return;
    }
  }

  // Generate key if not yet.
  $authkey = isset($node->authkey) ? $node->authkey : hash('sha256', drupal_random_bytes(64));

  // Save to DB.
  db_insert('node_authlink_nodes')
    ->fields(array(
    'nid' => $nid,
    'authkey' => $authkey,
    'created' => time(),
  ))
    ->execute();
}

/**
 * Implements hook_cron().
 */
function node_authlink_cron() {
  $node_types = node_type_get_types();
  foreach ($node_types as $type) {
    $expire = variable_get('node_authlink_expire_' . $type->type, 0);
    if (!$expire) {
      continue;
    }

    // NIDs of expired keys.
    $query = db_select('node', 'n');
    $query
      ->leftJoin('node_authlink_nodes', 'a', 'n.nid = a.nid');
    $query
      ->fields('n', array(
      'nid',
    ))
      ->condition('n.type', $type->type)
      ->condition('a.created', time() - $expire, '<');
    $nids = $query
      ->execute()
      ->fetchCol();

    // Regenerate keys.
    foreach ($nids as $nid) {
      db_delete('node_authlink_nodes')
        ->condition('nid', $nid)
        ->execute();
      node_authlink_node_insert($nid);
      if (module_exists('entitycache')) {
        cache_clear_all($nid, 'cache_entity_node');
      }
    }
  }
}

/**
 * Implements hook_token_info().
 */
function node_authlink_token_info() {
  $node['authlink:authkey'] = array(
    'name' => t("Authorization key"),
    'description' => t("Key generated by Node authorize link module."),
  );
  $node['authlink:view-url'] = array(
    'name' => t("View URL"),
    'description' => t("URL with authorization key."),
  );
  $node['authlink:edit-url'] = array(
    'name' => t("Edit URL"),
    'description' => t("URL with authorization key."),
  );
  $node['authlink:delete-url'] = array(
    'name' => t("Delete URL"),
    'description' => t("URL with authorization key."),
  );
  return array(
    'tokens' => array(
      'node' => $node,
    ),
  );
}

/**
 * Implements hook_tokens().
 */
function node_authlink_tokens($type, $tokens, array $data = array(), array $options = array()) {
  $replacements = array();
  if ($type == 'node' && !empty($data['node']->authkey)) {
    $node = $data['node'];
    foreach ($tokens as $name => $original) {
      switch ($name) {
        case 'authlink:authkey':
          $replacements[$original] = $node->authkey;
          break;
        case 'authlink:view-url':
          $replacements[$original] = node_authlink_get_url($node, 'view');
          break;
        case 'authlink:edit-url':
          $replacements[$original] = node_authlink_get_url($node, 'edit');
          break;
        case 'authlink:delete-url':
          $replacements[$original] = node_authlink_get_url($node, 'delete');
          break;
      }
    }
  }
  return $replacements;
}

/**
 * Implements hook_views_api().
 */
function node_authlink_views_api() {
  return array(
    'api' => 3,
  );
}

Functions

Namesort descending Description
node_authlink_batch_delete Callback: Delete authkeys for all nodes in node type.
node_authlink_batch_generate Callback: Generate authkeys for all nodes in node type.
node_authlink_cron Implements hook_cron().
node_authlink_form_node_type_form_alter Implements hook_form_node_type_form_alter().
node_authlink_form_node_type_form_alter_submit Callback: Submit for node_type_form.
node_authlink_get_url Get edit URL of specified node.
node_authlink_load_authkey Loads key from NID.
node_authlink_node_access Implements hook_node_access().
node_authlink_node_insert Implements hook_node_insert().
node_authlink_node_load Implements hook_node_load().
node_authlink_node_presave Implements hook_node_presave().
node_authlink_tokens Implements hook_tokens().
node_authlink_token_info Implements hook_token_info().
node_authlink_views_api Implements hook_views_api().