You are here

key.module in Key 7.2

Same filename and directory in other branches
  1. 8 key.module
  2. 7.3 key.module
  3. 7 key.module

Provides the ability to manage keys, which can be used by other modules.

File

key.module
View source
<?php

/**
 * @file
 * Provides the ability to manage keys, which can be used by other modules.
 */
define('KEY_MENU_PATH', 'admin/config/system/keys');

/**
 * Implements hook_permission().
 */
function key_permission() {
  return array(
    'administer keys' => array(
      'title' => t('Administer keys'),
      'description' => 'Create, edit, and delete keys.',
    ),
  );
}

/**
 * Implements hook_menu().
 */
function key_menu() {
  $items = array();
  $items[KEY_MENU_PATH] = array(
    'title' => 'Keys',
    'description' => 'Manage keys.',
    'page callback' => 'key_configs_list',
    'access arguments' => array(
      'administer keys',
    ),
    'file' => 'includes/key.admin.inc',
    'type' => MENU_NORMAL_ITEM,
  );
  $items[KEY_MENU_PATH . '/list'] = array(
    'title' => 'List keys',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
  );
  $items[KEY_MENU_PATH . '/add'] = array(
    'title' => 'Add key',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'key_config_form',
    ),
    'access arguments' => array(
      'administer keys',
    ),
    'file' => 'includes/key.admin.inc',
    'type' => MENU_LOCAL_ACTION,
  );
  $items[KEY_MENU_PATH . '/manage/%key_config'] = array(
    'title' => 'Edit key',
    'title callback' => 'key_config_edit_title',
    'title arguments' => array(
      5,
    ),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'key_config_form',
      5,
    ),
    'access arguments' => array(
      'administer keys',
    ),
    'file' => 'includes/key.admin.inc',
  );
  $items[KEY_MENU_PATH . '/manage/%key_config/delete'] = array(
    'title' => 'Delete key',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'key_config_delete_confirm',
      5,
    ),
    'access arguments' => array(
      'administer keys',
    ),
    'file' => 'includes/key.admin.inc',
  );
  return $items;
}

/**
 * Implements hook_theme().
 */
function key_theme() {
  return array(
    'key_configs_list_description' => array(
      'variables' => array(
        'label' => NULL,
        'name' => NULL,
        'description' => NULL,
      ),
      'file' => 'includes/key.admin.inc',
    ),
  );
}

/**
 * Implements hook_ctools_plugin_directory().
 *
 * Tell CTools where to find plugins for this module.
 */
function key_ctools_plugin_directory($module, $plugin) {
  if ($module == 'key' && !empty($plugin)) {
    return "plugins/{$plugin}";
  }
}

/**
 * Implements hook_ctools_plugin_type().
 *
 * Tell CTools about plugins the module uses.
 */
function key_ctools_plugin_type() {
  $plugins['key_provider'] = array(
    'cache' => TRUE,
    'cache table' => 'cache',
    'process' => '_key_provider_plugin_process',
    'defaults' => array(
      'title' => '',
      'description' => '',
      'key get value' => NULL,
      'config form validate' => NULL,
      'config form submit' => NULL,
      'delete form submit' => NULL,
      'dependency callback' => NULL,
      'dependency errors' => NULL,
      'provider settings form' => NULL,
      'key value form' => NULL,
      'key value obscure' => NULL,
      'allow base64 encoding' => TRUE,
    ),
  );
  return $plugins;
}

/**
 * Implements hook_element_info().
 */
function key_element_info() {
  $type['key'] = array(
    '#input' => TRUE,
    '#size' => 0,
    '#multiple' => FALSE,
    '#process' => array(
      '_key_element_expand',
      'form_process_select',
      'ajax_process_form',
    ),
    '#theme' => 'select',
    '#theme_wrappers' => array(
      'form_element',
    ),
    '#options' => array(),
    // Allow filtering of the list of key configurations.
    // See _key_filter_configs().
    '#filters' => array(),
    '#key_description' => TRUE,
  );
  return $type;
}

/**
 * Title callback for the key configuration edit page.
 *
 * @param string $config_name
 *   The machine-readable name of the configuration being edited.
 *
 * @return string
 *   The human-friendly label of the requested configuration.
 */
function key_config_edit_title($config) {
  return t('Edit @name key', array(
    '@name' => $config['label'],
  ));
}

/**
 * Menu argument loader: loads a key configuration by name.
 *
 * @param string $name
 *   The machine-readable name of an configuration to load,
 *   where '-' is replaced with '_'.
 *
 * @return array
 *   An array representing an key configuration or FALSE if the
 *   configuration does not exist.
 */
function key_config_load($name) {
  return key_get_config(strtr($name, array(
    '-' => '_',
  )));
}

/**
 * Process function to expand the key element.
 */
function _key_element_expand($element) {
  $element['#empty_option'] = t('Select a key');
  $element['#options'] = key_get_configs_as_options();
  if (!empty($element['#filters'])) {
    $element['#options'] = _key_configs_filter($element['#options'], $element['#filters']);
  }

  // Prefix the default description with a information about keys.
  if ($element['#key_description']) {
    $original_description = isset($element['#description']) ? $element['#description'] : '';
    $key_description = t('Choose an available key to use.');
    $key_description .= ' ' . t('If your key is not listed, <a href="@url">create a new key</a>.', array(
      '@url' => '/' . KEY_MENU_PATH,
    ));
    $element['#description'] = $key_description . ' ' . $original_description;
  }
  return $element;
}

/**
 * Filter an array of key configurations.
 */
function _key_configs_filter($configs, $filters) {
  $target_configs = array();
  foreach (key_get_configs() as $config) {
    $include = TRUE;
    if (!empty($filters['provider'])) {
      $include &= in_array($config['provider'], (array) $filters['provider']);
    }
    if ($include) {
      $target_configs[$config['name']] = TRUE;
    }
  }
  $configs = array_intersect_key($configs, $target_configs);
  return $configs;
}

/**
 * Gets information about all key providers.
 *
 * @param bool $all
 *   A flag indicating whether to include plugins with unmet dependencies.
 * @param bool $reset
 *   A flag indicating whether to clear the plugin cache. Otherwise, stale
 *   data may be returned if plugin properties have changed.
 *
 * @return array
 *   Information about all key providers.
 */
function key_get_providers($all = TRUE, $reset = FALSE) {
  if ($reset) {
    _key_clear_plugin_cache('key_provider');
  }
  ctools_include('plugins');
  $providers = ctools_get_plugins('key', 'key_provider');
  return $all ? $providers : array_filter($providers, '_key_plugin_is_valid');
}

/**
 * Gets all key providers as options, for use in forms.
 *
 * @param bool $all
 *   A flag indicating whether to include plugins with unmet dependencies.
 * @param bool $reset
 *   A flag indicating whether to clear the plugin cache. Otherwise, stale
 *   data may be returned if plugin properties have changed.
 *
 * @return array
 *   An array of key providers, with names for keys and labels for values.
 */
function key_get_providers_as_options($all = TRUE, $reset = FALSE) {
  $providers = key_get_providers($all, $reset);
  $options = array();
  foreach ($providers as $name => $provider) {
    $options[$name] = $provider['title'];
  }
  return $options;
}

/**
 * Gets information about a specific key provider.
 *
 * @param string $provider
 *   The name of the key provider to get.
 * @param bool $reset
 *   A flag indicating whether to clear the plugin cache. Otherwise, stale
 *   data may be returned if plugin properties have changed.
 *
 * @return array
 *   A key provider.
 */
function key_get_provider($provider, $reset = FALSE) {
  ctools_include('plugins');
  return ctools_get_plugins('key', 'key_provider', $provider);
}

/**
 * Gets information about all key configurations.
 *
 * @param bool $reset
 *   A flag to force the configurations to be retrieved from the database.
 *
 * @return array
 *   An array of configurations.
 */
function key_get_configs($reset = FALSE) {
  $configs =& drupal_static(__FUNCTION__);
  if (!isset($configs) || $reset) {
    $configs = db_query("SELECT * FROM {key_config} ORDER BY label ASC")
      ->fetchAllAssoc('name', PDO::FETCH_ASSOC);

    // Unserialize provider_settings field.
    foreach ($configs as $name => $config) {
      if (!empty($config['provider_settings'])) {
        $provider_settings = unserialize($config['provider_settings']);
        $configs[$name]['provider_settings'] = $provider_settings;
      }
    }
  }
  return $configs;
}

/**
 * Gets all key configurations as options, for use in forms.
 *
 * @param bool $reset
 *   A flag to force the configurations to be retrieved from the database.
 *
 * @return array
 *   An array of configurations, with names for keys and labels for values.
 */
function key_get_configs_as_options($reset = FALSE) {
  $options =& drupal_static(__FUNCTION__);
  if (!isset($options) || $reset) {
    $configs = key_get_configs($reset);
    $options = array();
    foreach ($configs as $name => $config) {
      $options[$name] = $config['label'];
    }
  }
  return $options;
}

/**
 * Gets information about a specific key configuration.
 *
 * @param string $name
 *   The machine name of the configuration to get.
 * @param bool $reset
 *   A flag to force the configuration to be retrieved from the database.
 *
 * @return array
 *   A key configuration.
 */
function key_get_config($name, $reset = FALSE) {
  $configs =& drupal_static(__FUNCTION__);
  if (!isset($configs) || $reset) {
    $configs = key_get_configs($reset);
  }
  if (array_key_exists($name, $configs)) {
    $config = $configs[$name];
  }
  else {
    $config = NULL;
  }
  return $config;
}

/**
 * Save a key configuration.
 *
 * @param array $fields
 *   The fields of the configuration to save.
 * @param bool $messages
 *   TRUE if messages should be displayed.
 */
function key_save_config($fields, $messages = TRUE) {

  // Load the key provider.
  $provider = key_get_provider($fields['provider']);

  // Serialize any field that is an array.
  foreach ($fields as $index => $field) {
    if (is_array($field)) {
      $fields[$index] = serialize($field);
    }
  }

  // If the created field is empty, set it to the request time.
  if (empty($fields['created'])) {
    $fields['created'] = REQUEST_TIME;
  }

  // If the changed field is empty, set it to the request time.
  if (empty($fields['changed'])) {
    $fields['changed'] = REQUEST_TIME;
  }

  // Save the configuration.
  $merge_status = db_merge('key_config')
    ->key(array(
    'name' => $fields['name'],
  ))
    ->fields($fields)
    ->execute();

  // Display message and log to watchdog.
  if ($messages) {
    $t_args = array(
      '%label' => $fields['label'],
    );
    switch ($merge_status) {
      case MergeQuery::STATUS_INSERT:
        drupal_set_message(t('The key %label has been added.', $t_args));
        watchdog('key', 'Added key %label.', $t_args, WATCHDOG_NOTICE, l(t('view'), KEY_MENU_PATH . '/list'));
        break;
      case MergeQuery::STATUS_UPDATE:
        drupal_set_message(t('The key %label has been updated.', $t_args));
        watchdog('key', 'Updated key %label.', $t_args, WATCHDOG_NOTICE, l(t('view'), KEY_MENU_PATH . '/list'));
        break;
    }
  }

  // Load the configuration to make sure it was saved.
  $key_config = key_get_config($fields['name'], TRUE);
  if (empty($key_config)) {
    return NULL;
  }

  // Return the saved configuration.
  return $key_config;
}

/**
 * Get a key using a key configuration.
 *
 * @param string $config_name
 *   The configuration name of the key to retrieve.
 *
 * @return string
 *   The key.
 */
function key_get_key($config_name) {
  $keys =& drupal_static(__FUNCTION__);

  // If the key already exists, return it.
  if (isset($keys[$config_name])) {
    return $keys[$config_name];
  }
  $config = key_get_config($config_name);

  // If the configuration doesn't exist, return NULL.
  if (!isset($config)) {
    return NULL;
  }
  $provider = key_get_provider($config['provider']);

  // Get the function to retrieve the key.
  $key_function = ctools_plugin_get_function($provider, 'key get value');

  // Retrieve the key.
  $key = call_user_func($key_function, $config);

  // Store the key, in case it's needed again.
  $keys[$config_name] = $key;
  return $key;
}

/**
 * Helper function to clear key plugin caches.
 */
function _key_clear_plugin_cache($type = NULL) {
  if ($type) {
    cache_clear_all("plugins:key:{$type}", 'cache');
  }
  else {
    cache_clear_all('plugins:key:', 'cache', TRUE);
  }
}

/**
 * Callback function to process key provider plugins.
 */
function _key_provider_plugin_process(&$plugin, $info) {

  // Check dependencies and attach any errors to the plugin.
  if ($dependency_function = ctools_plugin_get_function($plugin, 'dependency callback')) {
    $plugin['dependency errors'] = call_user_func($dependency_function);
  }
}

/**
 * Determine if a key provider plugin is valid.
 *
 * @param array $plugin
 *   The plugin to check.
 *
 * @return bool
 *   Whether or not the plugin is valid.
 */
function _key_plugin_is_valid($plugin) {
  if (empty($plugin['dependency errors'])) {
    return TRUE;
  }
  else {
    return FALSE;
  }
}

/**
 * Implements hook_features_api().
 *
 * Define the components that we want to make exportable, in this case
 * key configurations.
 */
function key_features_api() {
  return array(
    'key_config' => array(
      'name' => 'Keys',
      'file' => drupal_get_path('module', 'key') . '/includes/key_config.features.inc',
      'default_hook' => 'key_default_configs',
      'feature_source' => TRUE,
    ),
  );
}

Functions

Namesort descending Description
key_config_edit_title Title callback for the key configuration edit page.
key_config_load Menu argument loader: loads a key configuration by name.
key_ctools_plugin_directory Implements hook_ctools_plugin_directory().
key_ctools_plugin_type Implements hook_ctools_plugin_type().
key_element_info Implements hook_element_info().
key_features_api Implements hook_features_api().
key_get_config Gets information about a specific key configuration.
key_get_configs Gets information about all key configurations.
key_get_configs_as_options Gets all key configurations as options, for use in forms.
key_get_key Get a key using a key configuration.
key_get_provider Gets information about a specific key provider.
key_get_providers Gets information about all key providers.
key_get_providers_as_options Gets all key providers as options, for use in forms.
key_menu Implements hook_menu().
key_permission Implements hook_permission().
key_save_config Save a key configuration.
key_theme Implements hook_theme().
_key_clear_plugin_cache Helper function to clear key plugin caches.
_key_configs_filter Filter an array of key configurations.
_key_element_expand Process function to expand the key element.
_key_plugin_is_valid Determine if a key provider plugin is valid.
_key_provider_plugin_process Callback function to process key provider plugins.

Constants

Namesort descending Description
KEY_MENU_PATH @file Provides the ability to manage keys, which can be used by other modules.