You are here

regcode.admin.php in Registration codes 6

Same filename and directory in other branches
  1. 6.2 regcode.admin.php
  2. 7 regcode.admin.php

Functions and pages needed for the administration interface for the regcode module.

File

regcode.admin.php
View source
<?php

/**
 * @file
 * Functions and pages needed for the administration interface for the regcode module.
 */

/**
 * Return the form associated with the module settings.
 *
 * @return
 *   The settings form.
 */
function regcode_admin_settings() {
  $form = array();
  $form['regcode_fieldset_title'] = array(
    '#type' => 'textfield',
    '#title' => t('Field set title'),
    '#description' => t('The title of the registration code fieldset'),
    '#default_value' => variable_get('regcode_fieldset_title', 'Registration Code'),
  );
  $form['regcode_field_title'] = array(
    '#type' => 'textfield',
    '#title' => t('Field label'),
    '#description' => t('The label of the registration code textfield'),
    '#default_value' => variable_get('regcode_field_title', 'Registration Code'),
  );
  $form['regcode_field_description'] = array(
    '#type' => 'textfield',
    '#title' => t('Field description'),
    '#description' => t('The description under the registration code textfield'),
    '#default_value' => variable_get('regcode_field_description', 'Please enter your registration code.'),
  );
  $form['regcode_optional'] = array(
    '#type' => 'checkbox',
    '#title' => t('Make registration code optional'),
    '#default_value' => variable_get('regcode_optional', 0),
    '#description' => t('If checked, users can register without a registration code.'),
  );
  return system_settings_form($form);
}

/**
 * Page callback for reg code deletion.
 */
function regcode_admin_delete_confirm($rid) {
  if (empty($_GET['token']) || !drupal_valid_token($_GET['token'], $rid)) {
    MENU_ACCESS_DENIED;
  }
  regcode_admin_delete($rid);
  drupal_set_message(t('Code was deleted (Code #@code)', array(
    '@code' => $rid,
  )));
  drupal_goto('admin/user/regcodes/list');
}

/**
 * Create a registration code
 *
 * @return
 *   The settings form.
 */
function regcode_admin_create() {
  $form = array();

  // Basics
  $form['regcode_create'] = array(
    '#type' => 'fieldset',
    '#title' => t("Basics"),
    '#description' => t('Basic options for the new registration code'),
  );
  $form['regcode_create']['regcode_create_category'] = array(
    '#type' => 'textfield',
    '#title' => t("Category"),
    '#size' => 30,
    '#autocomplete_path' => 'admin/user/regcodes/autocomplete',
    '#description' => t('Assign a category for administration purposes, to aid code management.'),
  );
  $form['regcode_create']['regcode_create_code'] = array(
    '#type' => 'textfield',
    '#title' => t("Registration code"),
    '#description' => t('Leave blank to have code generated. Used as prefix when <em>Number of codes</em> is greater than 1.'),
  );
  $form['regcode_create']['regcode_create_maxuses'] = array(
    '#type' => 'textfield',
    '#title' => t("Maximum uses"),
    '#default_value' => 1,
    '#size' => 10,
    '#required' => TRUE,
    '#description' => t('How many times this code can be used to register (enter 0 for unlimited).'),
  );
  $form['regcode_create']['regcode_create_begins'] = array(
    '#type' => 'textfield',
    '#title' => t("Active from"),
    '#description' => t('When this code should activate (leave blank to activate immediately). Accepts any date format that strtotime can handle. Dates should be in between years 1980 and 2030.'),
    '#size' => 30,
  );
  $form['regcode_create']['regcode_create_expires'] = array(
    '#type' => 'textfield',
    '#title' => t("Expires on"),
    '#description' => t('When this code should expire (leave blank for no expiry). Accepts any date format that strtotime can handle. Dates should be in between years 1980 and 2030.'),
    '#size' => 30,
  );

  // Bulk
  $form['regcode_create_bulk'] = array(
    '#type' => 'fieldset',
    '#title' => t("Code generation"),
    '#description' => t('Settings used when generating codes'),
  );
  $form['regcode_create_bulk']['regcode_create_number'] = array(
    '#type' => 'textfield',
    '#title' => t("Number of codes to generate"),
    '#size' => 10,
    '#default_value' => 1,
    '#description' => t('The number of codes to generate'),
  );
  $form['regcode_create_bulk']['regcode_create_length'] = array(
    '#type' => 'textfield',
    '#title' => t("Code size"),
    '#size' => 10,
    '#default_value' => 10,
    '#description' => t('The length of the codes created'),
  );
  $form['regcode_create_bulk']['regcode_create_format'] = array(
    '#type' => 'select',
    '#default_value' => variable_get('regcode_generate_format', 'alpha'),
    '#title' => t('Format of the generated codes'),
    '#options' => array(
      'alpha' => t('Letters'),
      'numeric' => t('Numbers'),
      'alphanum' => t('Numbers & Letters'),
      'hexadec' => t('Hexadecimal'),
    ),
  );
  $form['regcode_create_bulk']['regcode_create_case'] = array(
    '#type' => 'checkbox',
    '#title' => t('Uppercase generated codes'),
    '#default_value' => variable_get('regcode_generate_case', ''),
  );
  $form['regcode_create_bulk_submit'] = array(
    '#type' => 'submit',
    '#value' => t("Create codes"),
  );
  return $form;
}

/**
 * Validator for create form
 */
function regcode_admin_create_validate($form, &$form_state) {
  foreach (array(
    'regcode_create_begins',
    'regcode_create_expires',
  ) as $field) {
    if (empty($form_state['values'][$field])) {
      continue;
    }
    $time = strtotime($form_state['values'][$field]);
    if (!$time) {
      form_set_error($field, t('Invalid date'));
    }
    $time = date("Y", $time);
    if ($time > 2030 || $time < 1980) {
      form_set_error($time, t('Date should be between years @start and @end.', array(
        '@start' => 1980,
        '@end' => 2030,
      )));
    }
  }
  if (!is_numeric($form_state['values']['regcode_create_maxuses']) || $form_state['values']['regcode_create_maxuses'] < 0) {
    form_set_error('regcode_create_maxuses', t('Invalid maxuses, specify a positive integer or enter "0" for unlimited'));
  }
}

/**
 * Submit handler for regcode_admin_create
 */
function regcode_admin_create_submit($form, &$form_state) {
  $code = array();

  // Convert dates into timestamps
  if (!empty($form_state['values']['regcode_create_begins'])) {
    $code['begins'] = strtotime($form_state['values']['regcode_create_begins']);
  }
  if (!empty($form_state['values']['regcode_create_expires'])) {
    $code['expires'] = strtotime($form_state['values']['regcode_create_expires']);
  }

  // Grab form values
  $code['is_active'] = 1;
  $code['category'] = $form_state['values']['regcode_create_category'];
  $code['maxuses'] = $form_state['values']['regcode_create_maxuses'];

  // Start creating codes
  module_load_include('regcode.api', 'regcode', 'php');
  for ($i = 0; $i < (int) $form_state['values']['regcode_create_number']; $i++) {
    $code['code'] = $form_state['values']['regcode_create_code'];

    // Generate a code
    if (empty($code['code']) || $form_state['values']['regcode_create_number'] > 1) {
      $gen = regcode_generate_code($form_state['values']['regcode_create_length'], $form_state['values']['regcode_create_format'], $form_state['values']['regcode_create_case']);
      $code['code'] .= $gen;
    }

    // Save code
    if (regcode_save_code($code, 'skip')) {
      drupal_set_message(t('Created registration code (%code)', array(
        '%code' => $code['code'],
      )));
    }
    else {
      drupal_set_message(t('Unable to create code (%code) as code already exists', array(
        '%code' => $code['code'],
      )), 'warning');
    }
  }
}

/**
 * Return the form associated with the registration code import admin page
 *
 * @return
 *   The import form array
 */
function regcode_admin_import() {

  // Build the descriptions
  $action_text = '<p>' . t('Action to perform when importing the data.') . '</p>';
  $action_text .= '<ul><li>' . t('<strong>Skip</strong>: Add new codes skipping those which already exists.') . '</li>';
  $action_text .= '<li>' . t('<strong>Overwrite</strong>: Add new codes overwriting those which already exist.') . '</li>';
  $action_text .= '<li>' . t('<strong>Clean</strong>: Erases <strong>all</strong> existing codes before importing new codes.') . '</li></ul>';
  $fieldorder_text = '<p>' . t('Comma separated list mapping regcode fields to CSV fields, e.g. "IGNORE, code, rid, info".') . '</p>';
  $fieldorder_text .= '<p>' . t('If you leave this field blank, the titles from the first row will be used.') . '</p>';

  // Add all of the available fields
  module_load_include('regcode.api', 'regcode', 'php');
  $fieldorder_text .= '<ul>';
  $fields = regcode_get_fields();
  foreach ($fields as $field => $value) {
    if ($value['#exposed'] === TRUE) {
      $fieldorder_text .= sprintf('<li><strong>%s</strong>: %s</li>', $field, $value['description']);
    }
  }
  $fieldorder_text .= '</ul>';

  // Build the form
  $form['#attributes']['enctype'] = 'multipart/form-data';
  $form['regcode_import_file'] = array(
    '#type' => 'file',
    '#title' => t("File"),
    '#description' => t('File upload with data to add/import (plaintext list or CSV format)'),
  );
  $form['regcode_import_action'] = array(
    '#type' => 'select',
    '#title' => t("Action"),
    '#default_value' => variable_get('regcode_import_action', 'skip'),
    '#options' => array(
      'skip' => t('Skip'),
      'overwrite' => t('Overwrite'),
      'clean' => t('Clean'),
    ),
    '#description' => $action_text,
  );
  $form['regcode_import_delimiter'] = array(
    '#type' => 'textfield',
    '#size' => 5,
    '#title' => t("Field delimiter"),
    '#description' => t('Character used as delimiter in csv import of registration codes'),
    '#default_value' => variable_get('regcode_import_delimiter', ','),
  );
  $form['regcode_import_enclosure'] = array(
    '#type' => 'textfield',
    '#size' => 5,
    '#title' => t("Text enclosure"),
    '#default_value' => variable_get('regcode_import_enclosure', '"'),
    '#description' => t('Character used as enclosure around text content fields on CSV import.'),
  );
  $form['regcode_import_fieldorder'] = array(
    '#type' => 'textfield',
    '#title' => t("Field order"),
    '#default_value' => variable_get('regcode_import_fieldorder', 'code'),
    '#description' => $fieldorder_text,
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Import'),
  );
  return $form;
}

/**
 * Handle the processing of a submitted import form
 *
 */
function regcode_admin_import_validate($form, &$form_state) {
  variable_set('regcode_import_delimiter', $form_state['values']['regcode_import_delimiter']);
  variable_set('regcode_import_enclosure', $form_state['values']['regcode_import_enclosure']);
  variable_set('regcode_import_fieldorder', $form_state['values']['regcode_import_fieldorder']);

  // Validators for file
  $validators = array(
    'file_validate_extensions' => array(
      'csv',
      'txt',
    ),
  );

  // Save the file
  if ($file = file_save_upload('regcode_import_file', $validators, file_directory_path())) {
    $form_state['values']['fileobj'] = $file;
    drupal_set_message(t('File successfully saved'));
  }
  else {
    form_set_error('regcode_import_file', t('Unable to parse CSV file'));
    return FALSE;
  }
}

/**
 * Handle the processing of a submitted import form
 *
 */
function regcode_admin_import_submit($form, &$form_state) {
  module_load_include('regcode.api', 'regcode', 'php');

  // Set some variblaes
  $action = $form_state['values']['regcode_import_action'];
  $delimiter = $form_state['values']['regcode_import_delimiter'];
  $enclosure = $form_state['values']['regcode_import_enclosure'];
  $fields = explode(',', $form_state['values']['regcode_import_fieldorder']);
  $fields = array_map('trim', $fields);
  $rows = $success = 0;

  // Check for clean
  if ($action === 'clean') {
    regcode_clean_codes('truncate');
  }

  // Parse and save
  $fh = fopen($form_state['values']['fileobj']->destination, 'r');
  while ($row = fgetcsv($fh, 1000, $delimiter, $enclosure)) {
    $rows++;
    $row = array_slice($row, 0, count($fields));
    $code = array_combine($fields, $row);

    // Check dates
    if (!empty($code['begins'])) {
      $code['begins'] = strtotime($code['begins']);
      if ($code['begins'] < 1) {
        continue;
      }
    }
    if (!empty($code['expires'])) {
      $code['expires'] = strtotime($code['expires']);
      if ($code['expires'] < 1) {
        continue;
      }
    }

    // Defaults
    if (empty($code['is_active'])) {
      $code['is_active'] = 1;
    }
    if (empty($code['maxuses'])) {
      $code['maxuses'] = 1;
    }
    $status = regcode_save_code($code, $action);
    if ($status) {
      $success++;
    }
  }

  // Status
  drupal_set_message(t('Successfully inserted @rows rows out of @total', array(
    '@rows' => $success,
    '@total' => $rows,
  )));

  // Close
  fclose($fh);
}

/**
 * Autocomplete helper for categories
 */
function regcode_admin_ajax_categories($string) {
  $matches = array();
  if (!empty($string)) {
    module_load_include('regcode.api', 'regcode', 'php');
    $matches = regcode_get_categories($string, 10);
  }
  print drupal_to_js($matches);
}

/**
 * Delete a rule
 */
function regcode_admin_delete($rid) {
  db_query('DELETE FROM {regcode} WHERE rid = %d', $rid);
}

/**
 * Return the code list page content with(in) the according filter form
 *
 * @return
 *   The settings form.
 */
function regcode_admin_list() {
  $form = array();

  // Pager heading text
  module_load_include('regcode.api', 'regcode', 'php');
  $visible = db_result(regcode_admin_list_getresource(true));
  $total = regcode_count();
  $form['filter'] = array(
    '#type' => 'fieldset',
    '#title' => t('Filter results: Showing @visible records out of @total', array(
      '@visible' => $visible,
      '@total' => $total,
    )),
    '#attributes' => array(
      'class' => 'container-inline',
    ),
  );

  // Load all of the available list filters
  regcode_admin_list_getfilters($form);

  // Load all of the available list actions
  regcode_admin_list_getactions($form);

  // Let other modules modify the form
  foreach (module_implements('regcode_filters') as $module) {
    $hook = $module . '_regcode_filters';
    $hook($form);
  }

  // Display the filtered list
  $form['list'] = array(
    '#value' => regcode_admin_list_getmarkup(),
  );
  return $form;
}

/**
 * Build form elements for all of the defined filters
 */
function regcode_admin_list_getfilters(&$form) {

  // Define common choices
  $all_map = array(
    '__all__' => t('-- All --'),
  );
  $boolean_map = array(
    '1' => t('Yes'),
    '0' => t('No'),
  );

  // Create a category filter
  module_load_include('regcode.api', 'regcode', 'php');
  $category_options = $all_map + drupal_map_assoc(regcode_categories());
  $form['filter']['filter_category'] = array(
    '#type' => 'select',
    '#title' => t('Category'),
    '#options' => $category_options,
    '#default_value' => variable_get('regcode_filter_category', '__all__'),
    '#weight' => 10,
  );

  // Create an is_active filter
  $is_active_options = $all_map + $boolean_map;
  $form['filter']['filter_is_active'] = array(
    '#type' => 'select',
    '#title' => t('Enabled'),
    '#options' => $is_active_options,
    '#default_value' => variable_get('regcode_filter_is_active', '__all__'),
    '#weight' => 20,
  );
}

/**
 * Build form elmeents for all of the actions available
 */
function regcode_admin_list_getactions(&$form) {

  // Create a filter list button
  $form['filter']['action_filter'] = array(
    '#type' => 'submit',
    '#value' => t('Filter list'),
    '#submit' => array(
      'regcode_admin_list_savefilters',
      'regcode_admin_list_action_filter',
    ),
    '#weight' => 30,
  );

  // Create a delete button
  $form['filter']['action_delete'] = array(
    '#type' => 'submit',
    '#value' => t('Delete codes'),
    '#submit' => array(
      'regcode_admin_list_savefilters',
      'regcode_admin_list_action_delete',
    ),
    '#weight' => 40,
  );

  // Create an export list button
  $form['filter']['action_export'] = array(
    '#type' => 'submit',
    '#value' => t('Export to CSV'),
    '#submit' => array(
      'regcode_admin_list_savefilters',
      'regcode_admin_list_action_export',
    ),
    '#weight' => 50,
  );
}

/**
 * Get all of the active filters from the form and save their form state
 *   in the variables table
 */
function regcode_admin_list_savefilters($form, $form_state) {
  foreach ($form['filter'] as $filter => $value) {
    if (substr($filter, 0, 6) !== 'filter') {
      continue;
    }
    if (isset($form_state['values'][$filter])) {
      $name = substr($filter, 7);
      variable_set('regcode_filter_' . $name, $form_state['values'][$filter]);
    }
  }
}

/**
 * Create an SQL WHERE string
 */
function regcode_admin_list_getwhere() {

  // Grab a list of current filters
  $resource = db_query("SELECT name,value FROM {variable} WHERE name LIKE 'regcode_filter_%'");

  // Build array of applicable conditions
  $conditions = array();
  while ($row = db_fetch_array($resource)) {
    $value = unserialize($row['value']);
    $filter = substr($row['name'], 15);

    // A value which is __all__ can be ignored
    if ($value === '__all__') {
      continue;
    }
    $conditions[$filter] = $value;
  }

  // Build the condition query string
  $cond = array();
  foreach ($conditions as $filter => $value) {
    $value = preg_replace('/[^a-zA-Z0-9\\s]+/', '', $value);
    $cond[] = sprintf("%s = '%s'", $filter, $value);
  }

  // Return the string
  $string = ' WHERE ';
  if (!empty($cond)) {
    $string .= implode($cond, ' AND ');
  }
  else {
    $string .= 'TRUE';
  }
  return $string;
}

/**
 * Grab the result resource based on the form state
 *
 * @param bool $count_only Return the rowcount only
 * @parma bool $conditions Use the variables table to filter the result set
 * @return resource The drupal result resource
 */
function regcode_admin_list_getresource($count_only = FALSE, $conditions = TRUE) {

  // Which query to use
  if ($count_only) {
    $query = 'SELECT COUNT(regcode.rid) AS count FROM {regcode} AS regcode';
  }
  else {
    module_load_include('regcode.api', 'regcode', 'php');

    // Prepend the table name
    $fields = regcode_get_fields();
    $f = array();
    foreach (array_keys($fields) as $field) {
      $f[] = 'regcode.' . $field;
    }
    $what = implode(',', $f);
    $query = 'SELECT ' . $what . ' FROM {regcode} AS regcode';
  }

  // Add conditions
  if ($conditions) {
    module_load_include('regcode.api', 'regcode', 'php');
    $query .= regcode_admin_list_getwhere();
  }

  // Allow plugins to alter the query
  foreach (module_implements('regcode_query_alter') as $module) {
    $hook = $module . '_regcode_query_alter';
    $hook($query, $count_only, $conditions);
  }
  return db_query($query);
}

/**
 * Return the marked up list for display
 */
function regcode_admin_list_getmarkup() {

  // Build a tablesort (automatically modifies the next db_query)
  module_load_include('regcode.api', 'regcode', 'php');
  $fields = regcode_get_fields();
  $header = array();
  $weight = 0;
  foreach ($fields as $field => $value) {
    $weight = ($weight / 10 + 1) * 10;
    $header[] = array(
      'data' => $value['#heading'],
      'field' => $field,
    );
  }
  $header[] = array(
    'data' => t('Actions'),
  );

  // Allow other modules to play with the headings
  foreach (module_implements('regcode_prepareheading') as $module) {
    $hook = $module . '_regcode_prepareheading';
    $hook($header);
  }

  // Query the database
  $sort = tablesort_sql($header);
  $result = regcode_admin_list_getresource();

  // Format the results
  $rows = array();
  while ($row = db_fetch_array($result)) {
    $rows[] = regcode_admin_list_preparerow($row);
  }

  // Output
  if (empty($rows)) {
    $output = '<p>&raquo; ' . t('No codes found.') . '</p>';
  }
  else {
    $output = theme('table', $header, $rows);
    $output .= theme('pager');
  }
  return $output;
}

/**
 * Format the raw records coming from the database into something
 *   more readable
 *
 * @param array $row The associative array of a current row
 * @return array The human readable array
 */
function regcode_admin_list_preparerow($row) {
  $row = array_map('check_plain', $row);

  // Date fields are integers. Safe to check_plain().
  $datefields = array(
    'created',
    'lastused',
    'begins',
    'expires',
  );

  // Format the dates
  foreach ($datefields as $date) {
    if (empty($row[$date])) {
      $row[$date] = '-';
    }
    else {
      $row[$date] = sprintf('<span title="%s">%s</span>', format_date(strtotime($row[$date])), format_date(strtotime($row[$date]), 'custom', 'Y/n/j'));
    }
  }

  // Format the booleans
  $row['is_active'] = $row['is_active'] ? 'Yes' : 'No';

  // Format the UID
  if (!empty($row['uid'])) {
    $row['uid'] = l($row['uid'], 'user/' . $row['uid']);
  }
  else {
    $row['uid'] = '-';
  }

  // Format the maxuses
  if ($row['maxuses'] === '0') {
    $row['maxuses'] = '-';
  }

  // Add actions
  $row['actions'] = l(t('Delete'), 'admin/user/regcodes/delete/' . $row['rid'], array(
    'query' => array(
      'token' => drupal_get_token($row['rid']),
    ),
  ));

  // Allow other modules to play with the row
  foreach (module_implements('regcode_preparerow') as $module) {
    $hook = $module . '_regcode_preparerow';
    $hook($row);
  }
  return $row;
}

/**
 * Regcode Action: Exports to CSV
 *
 * @param array $form
 * @param array $form_state
 */
function regcode_admin_list_action_export() {
  module_load_include('regcode.api', 'regcode', 'php');
  $result = regcode_admin_list_getresource();

  // Write a temporary file
  $filename = file_create_filename('regcode.csv', file_directory_temp());
  $fh = fopen($filename, 'w+');
  fputcsv($fh, array_keys(regcode_get_fields()));
  $i = 0;
  while ($row = db_fetch_array($result)) {
    $i++;
    fputcsv($fh, $row);
  }
  fclose($fh);

  // Output the right headers
  $headers = array(
    'Content-Type: text/csv',
    'Content-Disposition: attachment; filename="regcode.csv"',
  );
  file_transfer($filename, $headers);

  // Export
  drupal_set_message(t('#count records exported.', array(
    '#count' => $i,
  )));
}

/**
 * Mass delete rules
 */
function regcode_admin_list_action_delete() {

  // Build the query
  module_load_include('regcode.api', 'regcode', 'php');
  $query = 'DELETE FROM {regcode}';
  $query .= regcode_admin_list_getwhere();
  db_query($query);

  // Number of codes
  $num = db_affected_rows();
  drupal_set_message(t('#num codes have been deleted.', array(
    '#num' => $num,
  )));
  drupal_goto('admin/user/regcodes/list');
}

Functions

Namesort descending Description
regcode_admin_ajax_categories Autocomplete helper for categories
regcode_admin_create Create a registration code
regcode_admin_create_submit Submit handler for regcode_admin_create
regcode_admin_create_validate Validator for create form
regcode_admin_delete Delete a rule
regcode_admin_delete_confirm Page callback for reg code deletion.
regcode_admin_import Return the form associated with the registration code import admin page
regcode_admin_import_submit Handle the processing of a submitted import form
regcode_admin_import_validate Handle the processing of a submitted import form
regcode_admin_list Return the code list page content with(in) the according filter form
regcode_admin_list_action_delete Mass delete rules
regcode_admin_list_action_export Regcode Action: Exports to CSV
regcode_admin_list_getactions Build form elmeents for all of the actions available
regcode_admin_list_getfilters Build form elements for all of the defined filters
regcode_admin_list_getmarkup Return the marked up list for display
regcode_admin_list_getresource Grab the result resource based on the form state
regcode_admin_list_getwhere Create an SQL WHERE string
regcode_admin_list_preparerow Format the raw records coming from the database into something more readable
regcode_admin_list_savefilters Get all of the active filters from the form and save their form state in the variables table
regcode_admin_settings Return the form associated with the module settings.