You are here

scale.module in Quiz 6.6

The main file for scale.

Sponsored by: Norwegian Centre for Telemedicine Code: falcon

Scale question type for the Quiz module.

Allows the creation of scale questions (ex: likert scale)

File

question_types/scale/scale.module
View source
<?php

/**
 * The main file for scale.
 *
 * Sponsored by: Norwegian Centre for Telemedicine
 * Code: falcon
 *
 * @file
 * Scale question type for the Quiz module.
 *
 * Allows the creation of scale questions (ex: likert scale)
 */

/**
 * Implementation of hook_help().
 */
function scale_help($path, $args) {
  if ($path == 'admin/help#scale') {
    return t('This module provides a scale question type for Quiz.');
  }
}

/**
 * Implementation of hook_menu().
 */
function scale_menu() {
  $items['scale/collection/manage'] = array(
    'title' => t('Manage your preset collections'),
    'access callback' => 'user_access',
    'access arguments' => array(
      'create quiz question',
    ),
    'type' => MENU_SUGGESTED_ITEM,
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'scale_manage_collection_form',
    ),
  );
  return $items;
}

/**
 * Implementation of hook_theme
 *
 * @param $existing
 * @param $type
 * @param $theme
 * @param $path
 * @return array
 */
function scale_theme($existing, $type, $theme, $path) {
  return array(
    'scale_creation_form' => array(
      'arguments' => array(
        'form' => NULL,
      ),
    ),
  );
}

/**
 * Implementation of hook_perm()
 */
function scale_perm() {
  return array(
    'Edit global presets',
  );
}

/**
 * Implementation of hook_quiz_question_info().
 */
function scale_quiz_question_info() {
  return array(
    'scale' => array(
      'name' => 'Scale question',
      'description' => 'Quiz questions that allow a user to choose from a scale.',
      'question provider' => 'ScaleQuestion',
      'response provider' => 'ScaleResponse',
      'module' => 'quiz_question',
    ),
  );
}

/**
 * Implementation of hook_autoload_info().
 */
function scale_autoload_info() {
  return array(
    'ScaleQuestion' => array(
      'file' => 'scale.classes.inc',
    ),
    'ScaleResponse' => array(
      'file' => 'scale.classes.inc',
    ),
  );
}

/**
 * Implementation of hook_get_answer()
 */
function scale_get_answer($question_nid, $question_vid, $result_id) {
  $sql = "SELECT answer_id, question_vid, question_nid, result_id\n    FROM {quiz_scale_user_answers}\n    WHERE result_id = %d AND question_nid = %d AND question_vid = %d";
  $results = db_query($sql, $result_id);
  if (!$results) {
    return FALSE;
  }
  return db_fetch_array($results);
}

/**
 * Implementation of hook user.
 */
function scale_user($op, &$edit, &$account, $category = NULL) {
  switch ($op) {
    case 'delete':

      //Remove the users presets if they aren't in use.
      $sql = 'SELECT id
              FROM {quiz_scale_answer_collection} ac
              JOIN {quiz_scale_user} u ON(ac.id = u.answer_collection_id)
              WHERE uid = %d
              AND ac.for_all = 0
              AND ac.id NOT IN
                (SELECT answer_collection_id
                 FROM {quiz_scale_node_properties})
              AND ac.id NOT IN
                (SELECT answer_collection_id
                 FROM {quiz_scale_user}
                 WHERE NOT uid = %d)';
      $res = db_query($sql, $account->uid, $account->uid);
      while ($res_o = db_fetch_object($res)) {
        $sql = 'DELETE FROM {quiz_scale_answer}
            WHERE answer_collection_id = %d';
        db_query($sql, $res_o->id);
        $sql = 'DELETE FROM {quiz_scale_answer_collection}
            WHERE id = %d';
        db_query($sql, $res_o->id);
        $sql = 'DELETE FROM {quiz_scale_user}
            WHERE uid = %d';
        db_query($sql, $account->uid);
      }
      break;
  }
}

/**
 * Form for changing and deleting the current users question types.
 *
 * Users with the Edit global presets permissions can also add new global
 * presets here.
 *
 * @param $form_state
 * @return form
 */
function scale_manage_collection_form(&$form_state) {
  global $user;
  $scale_question = new ScaleQuestion(NULL);
  $collections = $scale_question
    ->getPresetCollections(user_access('Edit global presets'));
  if (user_access('Edit global presets')) {
    $new_col = new stdClass();
    $new_col->for_all = 1;
    $new_col->name = t('New global collection(available to all users)');
    $collections['new'] = $new_col;
  }
  $form = array();
  if (count($collections) == 0) {
    $form['no_col'] = array(
      '#value' => t('You don\'t have any preset collections'),
    );
    return $form;
  }
  foreach ($collections as $col_id => $obj) {
    $form["collection{$col_id}"] = array(
      '#type' => 'fieldset',
      '#title' => $collections[$col_id]->name,
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
    );
    $alternatives = $collections[$col_id]->alternatives;
    for ($i = 0; $i < variable_get('scale_max_num_of_alts', 10); $i++) {
      $form["collection{$col_id}"]["alternative{$i}"] = array(
        '#title' => t('Alternative !i', array(
          '!i' => $i + 1,
        )),
        '#size' => 60,
        '#maxlength' => 256,
        '#type' => 'textfield',
        '#default_value' => $alternatives[$i],
        '#required' => $i < 2 && $col_id != 'new',
      );
    }
    if ($col_id != 'new') {
      if (user_access('Edit global presets')) {
        $form["collection{$col_id}"]["for_all"] = array(
          '#type' => 'checkbox',
          '#title' => t("Available to all users"),
          '#default_value' => $collections[$col_id]->for_all,
        );
      }
      $form["collection{$col_id}"]["to-do"] = array(
        '#type' => 'radios',
        '#title' => t("What will you do?"),
        '#default_value' => '0',
        '#options' => array(
          t('Save changes, do not change questions using this preset'),
          t('Save changes, and change your own questions who uses this preset'),
          t('Delete this preset(This will not affect existing questions)'),
        ),
      );
    }
    else {
      $form["collection{$col_id}"]["to-do"] = array(
        '#type' => 'value',
        '#value' => 3,
      );
      $form["collection{$col_id}"]["for_all"] = array(
        '#type' => 'value',
        '#value' => 1,
      );
    }
  }
  $form['process'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );
  $form['#submit'][] = 'scale_collection_form_submit';
  if (user_access('Edit global presets')) {
    $form['#validate'][] = 'scale_collection_form_validate';
  }
  $form['#tree'] = TRUE;
  return $form;
}

/**
 * Handles the scale collection form.
 *
 * @param $form
 * @param $form_state
 */
function scale_collection_form_submit($form, &$form_state) {
  global $user;
  $changed = 0;
  $deleted = 0;
  foreach ($form_state['values'] as $key => $alternatives) {
    if ($col_id = _scale_get_col_id($key)) {
      $s_q = new ScaleQuestion(NULL);
      $s_q
        ->initUtil($col_id);
      switch ($alternatives['to-do']) {
        case 0:

        //Save, but don't change
        case 1:

          //Save and change existing questions
          $new_col_id = $s_q
            ->saveAnswerCollection(FALSE, $alternatives, 1);
          if (isset($alternatives['for_all'])) {
            _scale_set_for_all($new_col_id, $alternatives['for_all']);
          }
          if ($new_col_id == $col_id) {
            break;
          }
          $changed++;
          if ($alternatives['to-do'] == 0) {
            _scale_unpreset_collection($col_id, $user->uid);
            $s_q
              ->deleteCollectionIfNotUsed($col_id);
            if (isset($alternatives['for_all'])) {
              _scale_set_for_all($new_col_id, $alternatives['for_all']);
            }
          }
          elseif ($alternatives['to-do'] == 1) {
            $sql = 'UPDATE {quiz_scale_node_properties}
                    SET answer_collection_id = %d
                    WHERE answer_collection_id = %d
                    AND nid IN(
                      SELECT nid
                      FROM {node}
                      WHERE uid = %d
                    )';
            db_query($sql, $new_col_id, $col_id, $user->uid);
            db_query('DELETE FROM {quiz_scale_user} WHERE answer_collection_id = %d AND uid = %d', $col_id, $user->uid);
            $s_q
              ->deleteCollectionIfNotUsed($col_id);
          }
          break;
        case 2:

          //Delete
          $got_deleted = $s_q
            ->deleteCollectionIfNotUsed($col_id);
          if (!$got_deleted) {
            _scale_unpreset_collection($col_id, $user->uid);
          }
          $deleted++;
          break;
        case 3:

          //New
          if (strlen($alternatives['alternative0']) > 0) {
            $new_col_id = $s_q
              ->saveAnswerCollection(FALSE, $alternatives, 1);
            _scale_set_for_all($new_col_id, $alternatives['for_all']);
            drupal_set_message(t('New preset has been added'));
          }
          break;
      }
    }
  }
  if ($changed > 0) {
    drupal_set_message(t('!changed presets has been changed.', array(
      '!changed' => $changed,
    )));
  }
  if ($deleted > 0) {
    drupal_set_message(t('!deleted presets has been deleted.', array(
      '!deleted' => $deleted,
    )));
  }
}

/**
 * Validates the scale collection form
 *
 * @param $form
 * @param $form_state
 * @return unknown_type
 */
function scale_collection_form_validate($form, &$form_state) {
  if (strlen($form_state['values']['collectionnew']['alternative0']) > 0) {
    if (strlen($form_state['values']['collectionnew']['alternative1']) == 0) {
      form_set_error('collectionnew][alternative1', t('New preset must have atleast two alternatives.'));
    }
  }
}

/**
 * searches a string for the answer collection id
 *
 * @param $string
 * @return answer collection id
 */
function _scale_get_col_id($string) {
  $res = array();
  $success = preg_match('/^collection([0-9]{1,}|new)$/', $string, $res);
  return $success > 0 ? $res[1] : FALSE;
}

/**
 * Makes sure an answer collection isn't a preset for a given user.
 *
 * @param $col_id - answer_collection_id
 * @param $user_id
 */
function _scale_unpreset_collection($col_id, $user_id) {
  $sql = 'DELETE FROM {quiz_scale_user}
          WHERE answer_collection_id = %d AND uid = %d';
  db_query($sql, $col_id, $user_id);
  if (user_access('Edit global presets')) {
    $sql = 'UPDATE {quiz_scale_answer_collection}
            SET for_all = 0';
    db_query($sql);
  }
}

/**
 * Sets if a answer collection should be available for all question creators.
 *
 * @param $new_col_id - answer collection id
 * @param $for_all - 0 if not for all, 1 if for all
 */
function _scale_set_for_all($new_col_id, $for_all) {
  $sql = 'UPDATE {quiz_scale_answer_collection}
          SET for_all = %d
          WHERE id = %d';
  db_query($sql, $for_all, $new_col_id);
}
function theme_scale_creation_form($form) {
  $path = drupal_get_path('module', 'scale') . '/scale.js';
  drupal_add_js($path, 'module');
}

Functions

Namesort descending Description
scale_autoload_info Implementation of hook_autoload_info().
scale_collection_form_submit Handles the scale collection form.
scale_collection_form_validate Validates the scale collection form
scale_get_answer Implementation of hook_get_answer()
scale_help Implementation of hook_help().
scale_manage_collection_form Form for changing and deleting the current users question types.
scale_menu Implementation of hook_menu().
scale_perm Implementation of hook_perm()
scale_quiz_question_info Implementation of hook_quiz_question_info().
scale_theme Implementation of hook_theme
scale_user Implementation of hook user.
theme_scale_creation_form
_scale_get_col_id searches a string for the answer collection id
_scale_set_for_all Sets if a answer collection should be available for all question creators.
_scale_unpreset_collection Makes sure an answer collection isn't a preset for a given user.