You are here

regcode.module in Registration codes 7

Main functionality and hooks of regcode module.

File

regcode.module
View source
<?php

/**
 * @file
 * Main functionality and hooks of regcode module.
 */

// Define validation error codes.
define('REGCODE_VALIDITY_NOTEXISTING', 0);
define('REGCODE_VALIDITY_NOTAVAILABLE', 1);
define('REGCODE_VALIDITY_TAKEN', 2);
define('REGCODE_VALIDITY_EXPIRED', 3);
define('REGCODE_MODE_REPLACE', 0);
define('REGCODE_MODE_SKIP', 1);
define('REGCODE_CLEAN_TRUNCATE', 1);
define('REGCODE_CLEAN_INACTIVE', 3);
define('REGCODE_CLEAN_EXPIRED', 4);

/**
 * Implements hook_help().
 */
function regcode_help($path, $arg) {
  $output = '';
  switch ($path) {
    case 'admin/config/people/regcode':
      $output = '<p>' . t('View and manage created registration codes.') . '</p>';
      break;
    case 'admin/config/people/regcode/create':
      $output = '<p>' . t('Create manually or generate new registration codes.') . '</p>';
      break;
    case 'admin/config/people/regcode/manage':
      $output = '<p>' . t('Provides bulk management features for created registration codes.') . '</p>';
      break;
    case 'admin/config/people/regcode/settings':
      $output = '<p>' . t('Configure the registration code module.') . '</p>';
      break;
  }
  return $output;
}

/**
 * Implements hook_permission().
 */
function regcode_permission() {
  return array(
    'administer registration codes' => array(
      'title' => t('administer registration codes'),
      'description' => t('Configure the module and generate and delete registration codes'),
    ),
  );
}

/**
 * Implements hook_menu().
 */
function regcode_menu() {
  $items = array();
  $items['admin/config/people/regcode'] = array(
    'title' => 'Registration codes',
    'description' => 'Manage registration codes.',
    'file' => 'regcode.admin.php',
    'page callback' => 'regcode_admin_list',
    'access arguments' => array(
      'administer registration codes',
    ),
  );
  $items['admin/config/people/regcode/list'] = array(
    'title' => 'List',
    'description' => 'List of registration codes',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => 10,
  );
  $items['admin/config/people/regcode/create'] = array(
    'title' => 'Create',
    'description' => 'Create a registration code',
    'type' => MENU_LOCAL_TASK | MENU_LOCAL_ACTION,
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'regcode_admin_create',
    ),
    'access arguments' => array(
      'administer registration codes',
    ),
    'file' => 'regcode.admin.php',
    'weight' => 20,
  );
  $items['admin/config/people/regcode/manage'] = array(
    'title' => 'Manage',
    'description' => 'Manage the registration code database',
    'type' => MENU_LOCAL_TASK,
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'regcode_admin_manage',
    ),
    'access arguments' => array(
      'administer registration codes',
    ),
    'file' => 'regcode.admin.php',
    'weight' => 30,
  );
  $items['admin/config/people/regcode/settings'] = array(
    'title' => 'Settings',
    'description' => 'Settings for registration code functionality.',
    'type' => MENU_LOCAL_TASK,
    'access arguments' => array(
      'administer registration codes',
    ),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'regcode_admin_settings',
    ),
    'file' => 'regcode.admin.php',
    'weight' => 40,
  );
  return $items;
}

/**
 * Implements hook_entity_info().
 */
function regcode_entity_info() {
  return array(
    'regcode' => array(
      'label' => t('Registration Code'),
      'base table' => 'regcode',
      'entity keys' => array(
        'id' => 'rid',
        'label' => 'code',
      ),
    ),
  );
}

/**
 * Implements hook_field_extra_fields().
 */
function regcode_field_extra_fields() {
  $extra = array();
  $extra['user']['user'] = array(
    'form' => array(
      'regcode' => array(
        'label' => t('Registration code'),
        'description' => t('Registration code form elements.'),
        'weight' => -10,
      ),
    ),
    'display' => array(
      'regcode' => array(
        'label' => t('Registration code history'),
        'description' => t('Registration code history view element.'),
        'weight' => 5,
      ),
    ),
  );
  return $extra;
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function regcode_form_user_register_form_alter(&$form, &$form_state) {
  $code_optional = variable_get('regcode_optional', FALSE);
  $form['regcode'] = array(
    '#type' => 'textfield',
    '#title' => check_plain(variable_get('regcode_field_title', t('Registration Code'))),
    '#description' => check_plain(variable_get('regcode_field_description', t('Please enter your registration code.'))),
    '#required' => !($code_optional || user_access('administer users')),
    '#element_validate' => array(
      'regcode_code_element_validate',
    ),
  );

  // Capture the code from the url and inject it into the registration form.
  if (isset($_GET['regcode'])) {

    /*
     * Form API can handle potentially unsafe characters as long as they are
     * not printed directly. This code gets trimmed in regcode_code_validate().
     */
    $form['regcode']['#value'] = $_GET['regcode'];
    $form['regcode']['#description'] = NULL;
    $form['regcode']['#disabled'] = TRUE;
  }
}

/**
 * Validate the content of the code-field on user registration.
 */
function regcode_code_element_validate(&$element, &$form_state) {
  if (drupal_strlen(trim($element['#value']))) {
    $code = regcode_code_validate($element['#value']);
    if (!is_object($code)) {
      form_error($element, regcode_errormsg($code));
      watchdog('regcode', 'User entered invalid registration code (@code)', array(
        '@code' => $element['#value'],
      ), WATCHDOG_WARNING);
    }
  }
}

/**
 * Implements hook_user_insert().
 */
function regcode_user_insert(&$edit, $account) {
  $account->regcode = FALSE;
  if (empty($edit['regcode'])) {
    return;
  }
  $code = regcode_code_consume($edit['regcode'], $account->uid);
  if ($code) {
    $account->regcode = $code;
  }
  watchdog('regcode', 'The registration code %code was used by !user', array(
    '%code' => $edit['regcode'],
    '!user' => l($account->name, 'user/' . $account->uid),
  ));

  /*
   * Modules are expected to "consume" any data in the $edit array once it
   * has been used.
   */
  $edit['code'] = NULL;
}

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

/**
 * Implements hook_action_info().
 */
function regcode_action_info() {
  return array(
    'regcode_activate_action' => array(
      'type' => 'regcode',
      'label' => t('Activate codes'),
      'configurable' => FALSE,
      'triggers' => array(
        'any' => TRUE,
      ),
    ),
    'regcode_deactivate_action' => array(
      'type' => 'regcode',
      'label' => t('Deactive codes'),
      'configurable' => FALSE,
      'triggers' => array(
        'any' => TRUE,
      ),
    ),
    'regcode_delete_action' => array(
      'type' => 'regcode',
      'label' => t('Delete codes'),
      'configurable' => FALSE,
      'triggers' => array(
        'any' => TRUE,
      ),
    ),
    'regcode_tag_action' => array(
      'type' => 'regcode',
      'label' => t('Tag codes'),
      'configurable' => TRUE,
      'triggers' => array(
        'any' => TRUE,
      ),
    ),
  );
}

/**
 * Get the exposed regcode fields.
 *
 * @todo
 *   Make use of the entity API.
 *
 * @return array
 *   List of fields and their descriptions.
 */
function regcode_get_fields() {

  // Core exposed fields.
  $fields = array(
    'begins' => array(
      'description' => t('When code should be active from'),
      'title' => t('Begins'),
    ),
    'expires' => array(
      'description' => t('When code should expire'),
      'title' => t('Expires'),
    ),
    'code' => array(
      'description' => t('The registration code'),
      'title' => t('Code'),
    ),
    'is_active' => array(
      'description' => t('Whether the code is active'),
      'title' => t('Enabled'),
    ),
    'maxuses' => array(
      'description' => t('Maximum times the code can be used'),
      'title' => t('Max'),
    ),
    'uses' => array(
      'description' => t('Number of times the code has been used'),
      'title' => t('Uses'),
    ),
  );

  // Load contributed fields.
  $contrib = module_invoke_all('regcode_fields');
  if (is_array($contrib)) {
    $fields += $contrib;
  }
  return $fields;
}

/**
 * Return text message requested by given identifier/constant.
 *
 * @param int $err
 *   The error message code.
 *
 * @return string
 *   The text of the message.
 */
function regcode_errormsg($err) {
  $messages = array(
    REGCODE_VALIDITY_NOTEXISTING => t('Registration code does not exist'),
    REGCODE_VALIDITY_NOTAVAILABLE => t('Registration code is not available'),
    REGCODE_VALIDITY_TAKEN => t('Registration code has already been used'),
    REGCODE_VALIDITY_EXPIRED => t('Registration code has expired'),
  );
  $msg = FALSE;
  if (isset($messages[$err])) {
    $msg = $messages[$err];
  }
  return $msg;
}

/**
 * Load a registration code.
 *
 * @param int|null $id
 *   The database primary key (rid).
 * @param array $conditions
 *   An associative array containing the search conditions.
 *
 * @return object|bool
 *   The regcode object or FALSE if the code does not exist.
 *
 * @example
 *   regcode_load(1231); // Loads the regcode with rid=1231
 *   regcode_load(NULL, array('code'=>'foobar')); // Loads the "foobar" regcode
 */
function regcode_load_single($id, $conditions = array()) {

  // Build the query.
  $query = db_select('regcode')
    ->fields('regcode', array(
    'rid',
    'uid',
    'created',
    'lastused',
    'begins',
    'expires',
    'code',
    'is_active',
    'maxuses',
    'uses',
  ))
    ->range(0, 1);

  // Allow mixed search parameters.
  if (!empty($id)) {
    $query
      ->condition('rid', $id);
  }
  else {
    foreach ($conditions as $field => $value) {
      $query
        ->condition($field, $value);
    }
  }

  // Run the query and grab a single regcode.
  $regcode = $query
    ->execute()
    ->fetchObject();
  if (!$regcode) {
    return FALSE;
  }

  // Load the terms.
  $query = db_select('regcode_term')
    ->fields('term_data', array(
    'tid',
    'name',
  ))
    ->condition('regcode_term.rid', $regcode->rid);
  $query
    ->join('taxonomy_term_data', 'term_data', 'regcode_term.tid = term_data.tid');
  $tags = $query
    ->execute();
  $regcode->tags = array();
  foreach ($tags as $tag) {
    $regcode->tags[$tag->tid] = $tag->name;
  }

  /*
   * Entity loaders expect arrays of objects. entity_load and
   * this function both invoke the hook below.
   */
  $reg_codes = array(
    $regcode->rid => $regcode,
  );
  module_invoke_all('regcode_load', $reg_codes);
  return $reg_codes[$regcode->rid];
}

/**
 * Validate a regcode.
 *
 * @param string $regcode
 *   The regcode alphanumeric code.
 *
 * @return bool|int|object
 *   An error code, or the loaded regcode.
 */
function regcode_code_validate($regcode) {

  // Load the code.
  $code = regcode_load_single(NULL, array(
    'code' => trim($regcode),
  ));

  // Check validity.
  if ($code === FALSE) {
    return REGCODE_VALIDITY_NOTEXISTING;
  }
  if ($code->uses >= $code->maxuses && $code->maxuses !== '0') {
    return REGCODE_VALIDITY_TAKEN;
  }
  if (!$code->is_active) {
    return REGCODE_VALIDITY_NOTAVAILABLE;
  }
  if (!empty($code->begins) && $code->begins > REQUEST_TIME) {
    return REGCODE_VALIDITY_NOTAVAILABLE;
  }
  if (!empty($code->expires) && $code->expires < REQUEST_TIME) {
    return REGCODE_VALIDITY_EXPIRED;
  }
  return $code;
}

/**
 * Consume a regcode and attribute it to a user.
 *
 * @param string $regcode
 *   The registration code.
 * @param int $account_id
 *   Optional user id to assign the given code to.
 *
 * @return mixed
 *   An error code, or TRUE if the code was assigned successfully.
 */
function regcode_code_consume($regcode, $account_id) {
  $code = regcode_code_validate($regcode);

  // Check the code validated, otherwise return the error code.
  if (!is_object($code)) {
    return $code;
  }
  $code->uses++;

  // Mark the code inactive if it's used up.
  $active = 1;
  if ($code->maxuses != 0 && $code->uses >= $code->maxuses) {
    $active = 0;
  }

  // Use the code.
  db_update('regcode')
    ->fields(array(
    'uses' => $code->uses,
    'lastused' => REQUEST_TIME,
    'uid' => $account_id,
    'is_active' => $active,
  ))
    ->condition('rid', $code->rid)
    ->execute();

  // Trigger the regcode_used hook.
  $account = user_load($account_id);
  $account->regcode = $code;
  foreach (module_implements('regcode_used') as $module) {
    $hook = $module . '_regcode_used';
    $hook($code, $account);
  }

  // Notify rules module.
  if (is_object($code) && module_exists('rules')) {
    rules_invoke_event('regcode_used', $account, $code);
  }
  return $code;
}

/**
 * Gets the term ids associated with a registration code.
 *
 * @param object $code
 *   The registration code entity.
 *
 * @return array
 *   An array of term IDs.
 */
function regcode_get_term_ids(stdClass $code) {
  return array_keys($code->tags);
}

/**
 * Save given code to a record in the db and calls the regcode_presave hook.
 *
 * @todo
 *   Remove the $terms parameter and put it in the object
 *
 * @param object $code
 *   A code object (required fields are code, begins, expires, is_active, and
 *   maxuses.
 * @param array $terms
 *   An array of terms to associate this tag with.
 * @param int $action
 *   Action to perform when saving the code.
 *
 * @return bool
 *   TRUE if the code was saved.
 */
function regcode_save($code, $terms = array(), $action = REGCODE_MODE_REPLACE) {

  // Sanity check.
  if (empty($code) || empty($code->code)) {
    return FALSE;
  }

  // Trigger the regcode_save hook.
  foreach (module_implements('regcode_presave') as $module) {
    $hook = $module . '_regcode_presave';
    $hook($code, $terms);
  }

  // Insert mode.
  if ($action == REGCODE_MODE_REPLACE) {
    db_delete('regcode')
      ->condition('code', $code->code)
      ->execute();
  }

  // Insert.
  $rid = db_insert('regcode')
    ->fields(array(
    'created' => REQUEST_TIME,
    'begins' => empty($code->begins) ? NULL : (int) $code->begins,
    'expires' => empty($code->expires) ? NULL : (int) $code->expires,
    'code' => check_plain($code->code),
    'is_active' => isset($code->is_active) ? $code->is_active : 1,
    'maxuses' => isset($code->maxuses) ? (int) $code->maxuses : 1,
  ))
    ->execute();

  // Add tags.
  if (count($terms)) {
    foreach (array_filter($terms) as $tid => $enabled) {
      db_insert('regcode_term')
        ->fields(array(
        'rid' => $rid,
        'tid' => $tid,
      ))
        ->execute();
    }
  }
  return $rid;
}

/**
 * Delete regcode codes.
 *
 * @param int $op
 *   The operation ID.
 *
 * @return bool|object|int
 *   Boolean false if nothing happened. True if tables were empties. The number
 *   of deleted rows otherwise.
 */
function regcode_clean($op) {
  $res = FALSE;
  switch ($op) {
    case REGCODE_CLEAN_TRUNCATE:
      db_query('TRUNCATE {regcode}');
      db_query('TRUNCATE {regcode_term}');
      $res = TRUE;
      break;
    case REGCODE_CLEAN_EXPIRED:
      $res = db_delete('regcode')
        ->condition('expires', REQUEST_TIME, '<')
        ->execute();
      break;
    case REGCODE_CLEAN_INACTIVE:
      $res = db_delete('regcode')
        ->condition('is_active', 0)
        ->execute();
      break;
  }
  return $res;
}

/**
 * Generate a code.
 */
function regcode_generate($length, $output, $case) {
  static $seeded = FALSE;

  // Possible seeds.
  $outputs['alpha'] = 'abcdefghijklmnopqrstuvwqyz';
  $outputs['numeric'] = '0123456789';
  $outputs['alphanum'] = 'abcdefghijklmnopqrstuvwqyz0123456789';
  $outputs['hexadec'] = '0123456789abcdef';

  // Choose seed.
  if (isset($outputs[$output])) {
    $output = $outputs[$output];
  }

  // Seed generator (only do this once per invocation).
  if (!$seeded) {
    list($usec, $sec) = explode(' ', microtime());
    $seed = (double) $sec + (double) $usec * 100000;
    mt_srand($seed);
    $seeded = TRUE;
  }

  // Generate.
  $str = '';
  $output_count = strlen($output);
  for ($i = 0; $length > $i; $i++) {
    $str .= $output[mt_rand(0, $output_count - 1)];
  }
  if ($case) {
    $str = strtoupper($str);
  }
  return $str;
}

/**
 * Regcode delete action.
 */
function regcode_delete_action(&$object, $context = array()) {
  db_delete('regcode')
    ->condition('rid', $object->rid)
    ->execute();
}

/**
 * Regcode activate action.
 */
function regcode_activate_action(&$object, $context = array()) {
  db_update('regcode')
    ->fields(array(
    'is_active' => 1,
  ))
    ->condition('rid', $object->rid)
    ->execute();
}

/**
 * Regcode deactivate action.
 */
function regcode_deactivate_action(&$object, $context = array()) {
  db_update('regcode')
    ->fields(array(
    'is_active' => 0,
  ))
    ->condition('rid', $object->rid)
    ->execute();
}

/**
 * Regcode tag action.
 */
function regcode_tag_action(&$object, $context = array()) {

  // Apply terms.
  foreach ($context['apply_terms'] as $term) {
    $record = array(
      'rid' => $object->rid,
      'tid' => $term,
    );
    db_merge('regcode_term')
      ->key($record)
      ->fields($record)
      ->execute();
  }

  // Remove terms.
  foreach ($context['remove_terms'] as $term) {
    db_delete('regcode_term')
      ->condition('rid', $object->rid)
      ->condition('tid', $term)
      ->execute();
  }
}

/**
 * Form for tag_action.
 */
function regcode_tag_action_form() {
  $form = array();
  $form['regcode_apply_terms'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Apply tags'),
    '#description' => t('Select tags to be applied to the selected codes.'),
    '#options' => regcode_get_vocab_terms(),
  );
  $form['regcode_remove_terms'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Remove tags'),
    '#description' => t('Select tags to be remove to the selected codes.'),
    '#options' => regcode_get_vocab_terms(),
  );
  $vid = variable_get('regcode_vocabulary', 1);
  $text = t('You can <a href="!url">create tags</a> through the taxonomy module.', array(
    '!url' => url('admin/structure/taxonomy/' . $vid . '/add/term'),
  ));
  $form['regcode_taxonomy'] = array(
    '#value' => '<p>' . $text . '</p>',
  );
  return $form;
}

/**
 * Submit handler for tag_action.
 */
function regcode_tag_action_submit($form, $form_state) {
  return array(
    'apply_terms' => array_filter($form_state['values']['regcode_apply_terms']),
    'remove_terms' => array_filter($form_state['values']['regcode_remove_terms']),
  );
}

/**
 * Get a list of terms from the registration code vocabulary.
 */
function regcode_get_vocab_terms() {
  $tree = taxonomy_get_tree(variable_get('regcode_vocabulary', 1));
  $terms = array();
  foreach ($tree as $term) {
    $terms[$term->tid] = $term->name;
  }
  return $terms;
}

/**
 * Implements hook_token_info().
 */
function regcode_token_info() {
  $type = array(
    'name' => t('Registration Codes'),
    'description' => t('Replacement tokens for registration codes'),
    'needs-data' => 'regcode',
  );
  $regcode['created'] = array(
    'name' => t("Code creation time"),
    'description' => t("The date the regcode was created."),
    'type' => 'date',
  );
  $regcode['lastused'] = array(
    'name' => t("Code last used time"),
    'description' => t("The date the regcode was used last."),
    'type' => 'date',
  );
  $regcode['begins'] = array(
    'name' => t("Code activation date"),
    'description' => t("The date the regcode gets activated."),
    'type' => 'date',
  );
  $regcode['expires'] = array(
    'name' => t("Code expiry date"),
    'description' => t("The date the regcode expires."),
    'type' => 'date',
  );
  $regcode['code'] = array(
    'name' => t("Registration code"),
    'description' => t("One single registration code"),
  );
  $regcode['regurl'] = array(
    'name' => t("Registration URL"),
    'description' => t("Link to the registration page with regcode included"),
  );
  $regcode['is_active'] = array(
    'name' => t("State of the regcode"),
    'description' => t("Whether the code is active"),
  );
  $regcode['maxuses'] = array(
    'name' => t("Maximum usage count"),
    'description' => t("Maximum times a code can be used"),
  );
  $regcode['uses'] = array(
    'name' => t("Current usage count"),
    'description' => t("Number of times the code already has been used"),
  );
  return array(
    'types' => array(
      'regcode' => $type,
    ),
    'tokens' => array(
      'regcode' => $regcode,
    ),
  );
}

/**
 * Implements hook_tokens().
 */
function regcode_tokens($type, $tokens, array $data = array(), array $options = array()) {
  if (isset($options['language'])) {
    $language_code = $options['language']->language;
  }
  else {
    $language_code = NULL;
  }
  $replacements = array();
  if ($type == 'regcode' && !empty($data['regcode'])) {
    $regcode = $data['regcode'];
    foreach ($tokens as $name => $original) {
      switch ($name) {
        case 'created':
          $replacements[$original] = format_date($regcode->created, 'medium', '', NULL, $language_code);
          break;
        case 'lastused':
          $replacements[$original] = format_date($regcode->created, 'medium', '', NULL, $language_code);
          break;
        case 'begins':
          $replacements[$original] = format_date($regcode->created, 'medium', '', NULL, $language_code);
          break;
        case 'expires':
          $replacements[$original] = format_date($regcode->created, 'medium', '', NULL, $language_code);
          break;
        case 'code':
          $replacements[$original] = $regcode->code;
          break;
        case 'regurl':
          $replacements[$original] = url('user/register', array(
            'query' => array(
              'regcode' => $regcode->code,
            ),
            'absolute' => TRUE,
          ));
          break;
        case 'is_active':
          $replacements[$original] = $regcode->is_active ? t('active') : t('inactive');
          break;
        case 'maxuses':
          $replacements[$original] = $regcode->maxuses;
          break;
        case 'uses':
          $replacements[$original] = $regcode->uses;
          break;
      }
    }
    if ($created_tokens = token_find_with_prefix($tokens, 'created')) {
      $replacements += token_generate('date', $created_tokens, array(
        'date' => $regcode->created,
      ), $options);
    }
    if ($lastused_tokens = token_find_with_prefix($tokens, 'lastused')) {
      $replacements += token_generate('date', $lastused_tokens, array(
        'date' => $regcode->lastused,
      ), $options);
    }
    if ($begins_tokens = token_find_with_prefix($tokens, 'begins')) {
      $replacements += token_generate('date', $begins_tokens, array(
        'date' => $regcode->begins,
      ), $options);
    }
    if ($expires_tokens = token_find_with_prefix($tokens, 'expires')) {
      $replacements += token_generate('date', $expires_tokens, array(
        'date' => $regcode->expires,
      ), $options);
    }
  }
  return $replacements;
}

Functions

Namesort descending Description
regcode_action_info Implements hook_action_info().
regcode_activate_action Regcode activate action.
regcode_clean Delete regcode codes.
regcode_code_consume Consume a regcode and attribute it to a user.
regcode_code_element_validate Validate the content of the code-field on user registration.
regcode_code_validate Validate a regcode.
regcode_deactivate_action Regcode deactivate action.
regcode_delete_action Regcode delete action.
regcode_entity_info Implements hook_entity_info().
regcode_errormsg Return text message requested by given identifier/constant.
regcode_field_extra_fields Implements hook_field_extra_fields().
regcode_form_user_register_form_alter Implements hook_form_FORM_ID_alter().
regcode_generate Generate a code.
regcode_get_fields Get the exposed regcode fields.
regcode_get_term_ids Gets the term ids associated with a registration code.
regcode_get_vocab_terms Get a list of terms from the registration code vocabulary.
regcode_help Implements hook_help().
regcode_load_single Load a registration code.
regcode_menu Implements hook_menu().
regcode_permission Implements hook_permission().
regcode_save Save given code to a record in the db and calls the regcode_presave hook.
regcode_tag_action Regcode tag action.
regcode_tag_action_form Form for tag_action.
regcode_tag_action_submit Submit handler for tag_action.
regcode_tokens Implements hook_tokens().
regcode_token_info Implements hook_token_info().
regcode_user_insert Implements hook_user_insert().
regcode_views_api Implements hook_views_api().

Constants