You are here

webform_invitation.module in Webform Invitation 7

File

webform_invitation.module
View source
<?php

/**
 * Implements hook_menu().
 */
function webform_invitation_menu() {
  $items = array();
  $items['node/%/invitation'] = array(
    'title' => 'Invitation',
    'page callback' => 'webform_invitation_settings_page',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'webform_invitation_access_check',
    'access arguments' => array(
      1,
    ),
    'weight' => 10,
    'type' => MENU_LOCAL_TASK,
    'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
  );
  $items['node/%/invitation/settings'] = array(
    'title' => 'Settings',
    'page callback' => 'webform_invitation_settings_page',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'webform_invitation_access_check',
    'access arguments' => array(
      1,
    ),
    'weight' => -1,
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );
  $items['node/%/invitation/codes'] = array(
    'title' => 'List codes',
    'page callback' => 'webform_invitation_codes_page',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'webform_invitation_access_check',
    'access arguments' => array(
      1,
    ),
    'weight' => 0,
    'type' => MENU_LOCAL_TASK,
  );
  $items['node/%/invitation/generate'] = array(
    'title' => 'Generate',
    'page callback' => 'webform_invitation_generate_page',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'webform_invitation_access_check',
    'access arguments' => array(
      1,
    ),
    'weight' => 1,
    'type' => MENU_LOCAL_TASK,
  );
  $items['node/%/invitation/download'] = array(
    'title' => 'Download',
    'page callback' => 'webform_invitation_download_file',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'webform_invitation_access_check',
    'access arguments' => array(
      1,
    ),
    'weight' => 2,
    'type' => MENU_LOCAL_TASK,
  );
  return $items;
}
function webform_invitation_access_check($nid) {
  $node = node_load($nid);
  return $node->type == 'webform';
}
function webform_invitation_access() {

  // Is this required? If a user may edit a webform already, should there be a permission to control access to invitation mode?
}
function webform_invitation_settings_page($nid = null) {
  $out = drupal_get_form('webform_invitation_settings_form', $nid);
  return $out;
}
function webform_invitation_settings_form($form, &$form_state, $nid) {
  $db_setting = db_select('webform_invitation', 'i')
    ->fields('i')
    ->condition('nid', $nid, '=')
    ->execute()
    ->fetchAssoc();
  $form['nid'] = array(
    '#type' => 'hidden',
    '#value' => $nid,
  );
  $form['wi_enabled'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable invitations for this webform'),
    '#default_value' => $db_setting ? (int) $db_setting['invitation'] : 0,
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );
  return $form;
}
function webform_invitation_settings_form_submit($form, &$form_state) {
  global $base_url;
  $nid = $form_state['values']['nid'];
  $wi_enabled = $form_state['values']['wi_enabled'];
  db_merge('webform_invitation')
    ->key(array(
    'nid' => $nid,
  ))
    ->fields(array(
    'invitation' => $wi_enabled,
  ))
    ->execute();
  if ($wi_enabled == 1) {
    drupal_set_message(t('Invitation mode has been activated. You should now <a href="!base_url/node/!nid/invitation/generate">create some invitation codes</a>.', array(
      '!base_url' => $base_url,
      '!nid' => $nid,
    )));
    $node = node_load($nid);
    $field_present = false;
    foreach ($node->webform['components'] as $id => $com) {
      if ($com['form_key'] == 'webform_invitation_code') {
        $field_present = true;
        break;
      }
    }
    if ($field_present == false) {
      $newid = max(array_keys($node->webform['components'])) + 1;
      $code_box = array(
        'nid' => $nid,
        'cid' => $newid,
        'pid' => 0,
        'form_key' => 'webform_invitation_code',
        'name' => t('Invite Code'),
        'type' => 'textfield',
        'value' => '%get[code]',
        'extra' => array(
          'description' => t('Enter your personal invitation code (only applies if the field is not populated yet).'),
          'title_display' => 'inline',
          'private' => 0,
          'disabled' => 0,
          'unique' => 1,
          'maxlength' => 64,
          'conditional_operator' => '=',
          'width' => '',
          'field_prefix' => '',
          'field_suffix' => '',
          'attributes' => array(),
          'conditional_component' => '',
          'conditional_values' => '',
        ),
        'mandatory' => 1,
        'weight' => 0,
        'page_num' => 1,
      );
      $node->webform['components'][$newid] = $code_box;
      node_save($node);
    }
  }
  else {
    drupal_set_message(t('Invitation mode has been disabled.'));
    $node = node_load($nid);
    foreach ($node->webform['components'] as $id => $com) {
      if ($com['form_key'] == 'webform_invitation_code') {
        unset($node->webform['components'][$id]);
        node_save($node);
        break;
      }
    }
  }
}
function webform_invitation_codes_page($nid = null) {
  $codes = db_select('webform_invitation_codes', 'c')
    ->fields('c')
    ->condition('nid', $nid, '=')
    ->execute()
    ->fetchAll();
  $node = node_load($nid);
  $out = "<h2>" . t('Invitation codes for webform %node_title', array(
    "%node_title" => $node->title,
  )) . "</h2>";
  if (count($codes) > 0) {
    $out .= "<table><tr><th>" . t('Code') . "</th><th>" . t('used?') . "</th></tr>";
    foreach ($codes as $code) {
      $out .= '<tr><td>' . $code->code . '</td><td>' . ($code->used != null ? t('yes') : t('no')) . '</td></tr>';
    }
    $out .= '</table>';
  }
  else {
    $out .= '<p><em>' . t('No codes present, yet. Click on "Generate" above to create codes.') . '</em></p>';
  }
  return $out;
}
function webform_invitation_generate_page($nid = null) {
  $out = drupal_get_form('webform_invitation_generate_form', $nid);
  return $out;
}
function webform_invitation_generate_form($form, &$form_state, $nid) {
  $form['intro'] = array(
    '#markup' => '<p>' . t('To generate codes please enter the required number of codes and hit the button.') . '</p>',
  );
  $form['nid'] = array(
    '#type' => 'hidden',
    '#value' => $nid,
  );
  $form['number_of_tokens'] = array(
    '#type' => 'textfield',
    '#title' => t('# of codes to generate'),
    '#default_value' => array(
      25,
    ),
    '#element_validate' => array(
      'webform_invitation_validate_numeric_count',
    ),
    '#required' => true,
  );
  $form['options'] = array(
    '#type' => 'fieldset',
    '#title' => t('Options'),
    '#collapsible' => true,
    '#collapsed' => true,
  );
  $form['options']['type_of_tokens'] = array(
    '#type' => 'radios',
    '#title' => t('type of tokens'),
    '#default_value' => 1,
    '#options' => array(
      1 => t('md5 hash (32 characters)'),
      99 => t('custom'),
    ),
  );
  $form['options']['length_of_tokens'] = array(
    '#type' => 'textfield',
    '#title' => t('length of tokens (number of characters)'),
    '#default_value' => array(
      32,
    ),
    '#element_validate' => array(
      'webform_invitation_validate_numeric_length',
    ),
    '#states' => array(
      'invisible' => array(
        ':input[name="type_of_tokens"]' => array(
          'value' => 1,
        ),
      ),
    ),
  );
  $form['options']['chars_of_tokens'] = array(
    '#type' => 'checkboxes',
    '#title' => t('characters to be used for tokens'),
    '#default_value' => array(
      1,
      2,
      3,
    ),
    '#options' => array(
      1 => t('lower case letters (a-z)'),
      2 => t('upper case letters (A-Z)'),
      3 => t('digits (0-9)'),
      4 => t('punctuation (.,:;-_!?'),
    ),
    '#element_validate' => array(
      'webform_invitation_validate_option_count',
    ),
    '#states' => array(
      'invisible' => array(
        ':input[name="type_of_tokens"]' => array(
          'value' => 1,
        ),
      ),
    ),
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Generate'),
  );
  return $form;
}
function webform_invitation_validate_numeric_count($element, &$form_state) {
  if (!preg_match('/^\\d+$/', $element['#value'])) {
    form_error($element, t('Enter an integer only.'));
  }
  elseif ($element['#value'] < 0) {
    form_error($element, t('Enter a number greater than zero.'));
  }
}
function webform_invitation_validate_numeric_length($element, &$form_state) {
  if (!preg_match('/^\\d+$/', $element['#value'])) {
    form_error($element, t('Enter an integer only.'));
  }
  elseif ($element['#value'] < 5 || $element['#value'] > 64) {
    form_error($element, t('The length must be between 5 and 64.'));
  }
}
function webform_invitation_validate_option_count($element, &$form_state) {
  if (count($element['#value']) == 0) {
    form_error($element, t('Choose at least one character subset.'));
  }
}
function webform_invitation_generate_form_submit($form, &$form_state) {
  $number = $form_state['values']['number_of_tokens'];
  $nid = $form_state['values']['nid'];
  if ($form_state['values']['type_of_tokens'] == 1) {
    $i = $l = 1;
    while ($i <= $number && $l < $number * 10) {

      // Code generation
      $code = md5(microtime(1) * rand());
      try {

        // Insert code to DB
        $tmpres = db_insert('webform_invitation_codes')
          ->fields(array(
          'nid' => $nid,
          'code' => $code,
          'generated' => REQUEST_TIME,
          'used' => null,
        ))
          ->execute();
        $i++;
      } catch (PDOException $e) {

        // The generated code is already in DB; make another one.
      }
      $l++;
    }
  }
  elseif ($form_state['values']['type_of_tokens'] == 99) {
    $length = $form_state['values']['length_of_tokens'];
    $char_sets = $form_state['values']['chars_of_tokens'];
    $chars = '';
    if (in_array(1, $char_sets)) {
      $chars .= 'abcdefghijklmnopqrstuvwxyz';
    }
    if (in_array(2, $char_sets)) {
      $chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    }
    if (in_array(3, $char_sets)) {
      $chars .= '0123456789';
    }
    if (in_array(4, $char_sets)) {
      $chars .= '.,:;-_!?';
    }
    $i = $l = 1;
    while ($i <= $number && $l < $number * 10) {

      // Code generation
      $code = '';
      for ($j = 1; $j <= $length; $j++) {
        $code .= $chars[rand(0, strlen($chars) - 1)];
      }
      try {
        $tmpres = db_insert('webform_invitation_codes')
          ->fields(array(
          'nid' => $nid,
          'code' => $code,
          'generated' => REQUEST_TIME,
          'used' => null,
        ))
          ->execute();
        $i++;
      } catch (PDOException $e) {

        // The generated code is already in DB; make another one.
      }
      $l++;
    }
  }
  if ($l >= $number * 10) {
    drupal_set_message(t('Due to unique constraint, only @ccount codes have been generated.', array(
      '@ccount' => $i - 1,
    )), 'error');
  }
  drupal_goto('node/' . $nid . '/invitation/codes');
}
function webform_invitation_form_alter(&$form, &$form_state, $form_id) {
  if (substr($form_id, 0, 20) == 'webform_client_form_') {
    $nid = $form['#node']->nid;
    if ($nid > 0) {
      $db_setting = db_select('webform_invitation', 'i')
        ->fields('i')
        ->condition('nid', $nid, '=')
        ->execute()
        ->fetchAssoc();
      if ($db_setting['invitation'] == "1") {
        $form['#validate'][] = 'webform_invitation_code_validate';
      }
    }
  }
  return $form;
}
function webform_invitation_code_validate($form, &$form_state) {
  if (isset($form_state['values']['submitted']['webform_invitation_code'])) {
    $code = $form_state['values']['submitted']['webform_invitation_code'];
    $result = db_select('webform_invitation_codes', 'c')
      ->fields('c')
      ->condition('code', $code, '=')
      ->execute()
      ->fetchAssoc();
    if (!isset($result) || $result == null) {
      form_set_error('webform_invitation_code', 'This code is not valid.');
    }
    elseif ($result['used'] > 0) {

      // Not required, handled by webform => UNIQUE option.

      #form_set_error('invitation_code', 'This code has already been used.');
    }
    else {

      // valid code, update db
      $num = db_update('webform_invitation_codes')
        ->fields(array(
        'used' => REQUEST_TIME,
      ))
        ->condition('code', $code, '=')
        ->execute();
    }
  }
}
function webform_invitation_download_file($nid) {
  global $base_url;

  //this is the XLS header:
  $xlshead = pack("s*", 0x809, 0x8, 0x0, 0x10, 0x0, 0x0);

  //this is the XLS footer:
  $xlsfoot = pack("s*", 0xa, 0x0);
  $codes = db_select('webform_invitation_codes', 'c')
    ->fields('c')
    ->condition('nid', $nid, '=')
    ->execute();
  $node = node_load($nid);
  $data = "";
  $row = 0;
  while ($code = $codes
    ->fetchAssoc()) {
    $data .= webform_invitation_xlsCell($row, 0, $base_url . "/" . drupal_get_path_alias("node/" . $nid) . '?code=' . $code['code']);
    $row++;
  }
  $filename = "codes-" . $nid . ".xls";
  header("Content-Type: application/force-download");
  header("Content-Type: application/octet-stream");
  header("Content-Type: application/download");
  header("Content-Disposition: attachment;filename={$filename}");
  header("Content-Transfer-Encoding: binary ");
  echo $xlshead . $data . $xlsfoot;
  exit;

  //this is important!
}
function webform_invitation_xlsCell($row, $col, $val) {
  $len = strlen($val);
  return pack("s*", 0x204, 8 + $len, $row, $col, 0x0, $len) . $val;
}