You are here

function quiz_form in Quiz 7.5

Same name and namespace in other branches
  1. 5.2 quiz.module \quiz_form()
  2. 5 quiz.module \quiz_form()
  3. 6.6 quiz.module \quiz_form()
  4. 6.2 quiz.module \quiz_form()
  5. 6.3 quiz.module \quiz_form()
  6. 6.4 quiz.module \quiz_form()
  7. 6.5 quiz.module \quiz_form()
  8. 7.6 quiz.module \quiz_form()
  9. 7 quiz.module \quiz_form()
  10. 7.4 quiz.module \quiz_form()

Implements hook_form().

This is an admin form used to build a new quiz. It is called as part of the node edit form.

1 call to quiz_form()
quiz_admin_node_form in ./quiz.admin.inc
Renders the quiz node form for the admin pages.

File

./quiz.module, line 1147
quiz.module Main file for the Quiz module.

Code

function quiz_form(&$node, &$form_state) {
  $form = array();

  // We tell quiz_form_alter to check for the manual revisioning permission.
  $form['#quiz_check_revision_access'] = TRUE;
  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title'),
    '#default_value' => isset($node->title) ? $node->title : '',
    '#description' => t('The name of this @quiz.', array(
      '@quiz' => QUIZ_NAME,
    )),
    '#required' => TRUE,
  );
  $quiz_result_types = quiz_result_types();
  foreach ($quiz_result_types as $quiz_result_type => $type_info) {
    $quiz_result_type_options[$quiz_result_type] = $type_info->label;
  }
  $form['result_type'] = array(
    '#title' => t('Result type'),
    '#type' => 'select',
    '#options' => $quiz_result_type_options,
    '#default_value' => isset($node->quiz->result_type) ? $node->quiz->result_type : NULL,
    '#description' => t("Before starting the quiz, the fields on this result type will be displayed to the user."),
  );
  $form['taking'] = array(
    '#type' => 'fieldset',
    '#title' => t('Taking options'),
    '#collapsed' => isset($settings_loaded) ? $settings_loaded : FALSE,
    '#collapsible' => TRUE,
    '#attributes' => array(
      'id' => 'taking-fieldset',
    ),
    '#group' => 'additional_settings',
    '#weight' => -2,
  );
  $form['taking']['allow_resume'] = array(
    '#type' => 'checkbox',
    '#title' => t('Allow resume'),
    '#default_value' => $node->allow_resume,
    '#description' => t('Allow users to leave this @quiz incomplete and then resume it from where they left off.', array(
      '@quiz' => QUIZ_NAME,
    )),
  );
  $form['taking']['allow_skipping'] = array(
    '#type' => 'checkbox',
    '#title' => t('Allow skipping'),
    '#default_value' => $node->allow_skipping,
    '#description' => t('Allow users to skip questions in this @quiz.', array(
      '@quiz' => QUIZ_NAME,
    )),
  );
  $form['taking']['allow_jumping'] = array(
    '#type' => 'checkbox',
    '#title' => t('Allow jumping'),
    '#default_value' => $node->allow_jumping,
    '#description' => t('Allow users to jump to any question using a menu or pager in this @quiz.', array(
      '@quiz' => QUIZ_NAME,
    )),
  );
  $form['taking']['allow_change'] = array(
    '#type' => 'checkbox',
    '#title' => t('Allow changing answers'),
    '#default_value' => $node->allow_change,
    '#description' => t('If the user is able to visit a previous question, allow them to change the answer.'),
  );
  $form['taking']['allow_change_blank'] = array(
    '#type' => 'checkbox',
    '#title' => t('Allow changing blank answers'),
    '#default_value' => $node->allow_change_blank,
    '#description' => t('If the user is able to visit a previous skipped question, allow them to enter an answer.'),
    '#states' => array(
      'visible' => array(
        '#edit-allow-change' => array(
          'checked' => FALSE,
        ),
      ),
    ),
  );
  $form['taking']['backwards_navigation'] = array(
    '#type' => 'checkbox',
    '#title' => t('Backwards navigation'),
    '#default_value' => $node->backwards_navigation,
    '#description' => t('Allow users to go back and revisit questions already answered.'),
  );
  $form['taking']['repeat_until_correct'] = array(
    '#type' => 'checkbox',
    '#title' => t('Repeat until correct'),
    '#default_value' => $node->repeat_until_correct,
    '#description' => t('Require the user to retry the question until answered correctly.'),
  );
  $form['taking']['build_on_last'] = array(
    '#type' => 'radios',
    '#options' => array(
      '' => t('Fresh attempt every time'),
      'correct' => t('Prepopulate with correct answers from last result'),
      'all' => t('Prepopulate with all answers from last result'),
    ),
    '#title' => t('Each attempt builds on the last'),
    '#default_value' => $node->build_on_last,
    '#description' => t('Instead of starting a fresh @quiz, users can base a new attempt on the last attempt, with correct answers prefilled. Set the default selection users will see. Selecting "fresh attempt every time" will not allow the user to choose.', array(
      '@quiz' => QUIZ_NAME,
    )),
  );
  $form['taking']['mark_doubtful'] = array(
    '#type' => 'checkbox',
    '#title' => t('Mark doubtful'),
    '#default_value' => $node->mark_doubtful,
    '#description' => t('Allow users to mark their answers as doubtful.'),
  );
  $form['taking']['show_passed'] = array(
    '#type' => 'checkbox',
    '#title' => t('Show passed status'),
    '#default_value' => $node->show_passed,
    '#description' => t('Show a message if the user has previously passed the @quiz.', array(
      '@quiz' => QUIZ_NAME,
    )),
  );
  $form['taking']['randomization'] = array(
    '#type' => 'radios',
    '#title' => t('Randomize questions'),
    '#options' => array(
      t('No randomization'),
      t('Random order'),
      t('Random questions'),
      t('Categorized random questions'),
    ),
    '#description' => t('<strong>Random order</strong> - all questions display in random order') . '<br/>' . t("<strong>Random questions</strong> - specific number of questions are drawn randomly from this @quiz's pool of questions", array(
      '@quiz' => QUIZ_NAME,
    )) . '<br/>' . t('<strong>Categorized random questions</strong> - specific number of questions are drawn from each specified taxonomy term'),
    '#default_value' => $node->randomization,
  );
  $form['taking']['review_options'] = array(
    '#type' => 'fieldset',
    '#title' => t('Review options'),
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
    '#tree' => TRUE,
    '#description' => t('Control what feedback appears and when. To display any per-question feedback, one of the "Question" review options must be enabled.'),
  );
  $review_options = quiz_get_feedback_options();
  foreach (quiz_get_feedback_times() as $key => $when) {
    $form['taking']['review_options'][$key] = array(
      '#title' => $when['name'],
      '#type' => 'checkboxes',
      '#options' => $review_options,
      '#default_value' => isset($node->review_options[$key]) ? $node->review_options[$key] : array(),
    );
  }
  $options = array(
    t('Unlimited'),
  );
  for ($i = 1; $i < 10; $i++) {
    $options[$i] = $i;
  }
  $form['taking']['multiple_takes'] = array(
    '#type' => 'fieldset',
    '#title' => t('Multiple takes'),
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
    '#attributes' => array(
      'id' => 'multiple-takes-fieldset',
    ),
    '#description' => t('Allow users to take this @quiz multiple times.', array(
      '@quiz' => QUIZ_NAME,
    )),
  );
  $form['taking']['multiple_takes']['takes'] = array(
    '#type' => 'select',
    '#title' => t('Allowed number of attempts'),
    '#default_value' => $node->takes,
    '#options' => $options,
    '#description' => t('The number of times a user is allowed to take this @quiz. <strong>Anonymous users are only allowed to take @quiz that allow an unlimited number of attempts.</strong>', array(
      '@quiz' => QUIZ_NAME,
    )),
  );
  $form['taking']['multiple_takes']['show_attempt_stats'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display allowed number of attempts'),
    '#default_value' => $node->show_attempt_stats,
    '#description' => t('Display the allowed number of attempts on the starting page for this @quiz.', array(
      '@quiz' => QUIZ_NAME,
    )),
  );
  if (user_access('delete any quiz results') || user_access('delete results for own quiz')) {
    $form['taking']['multiple_takes']['keep_results'] = array(
      '#type' => 'radios',
      '#title' => t('Store results'),
      '#description' => t('These results should be stored for each user.'),
      '#options' => array(
        t('The best'),
        t('The newest'),
        t('All'),
      ),
      '#default_value' => $node->keep_results,
    );
  }
  else {
    $form['taking']['multiple_takes']['keep_results'] = array(
      '#type' => 'value',
      '#value' => $node->keep_results,
    );
  }
  $form['taking']['time_limit'] = array(
    '#type' => 'textfield',
    '#title' => t('Time limit'),
    '#default_value' => isset($node->time_limit) ? $node->time_limit : 0,
    '#description' => t('Set the maximum allowed time in seconds for this @quiz. Use 0 for no limit.', array(
      '@quiz' => QUIZ_NAME,
    )) . '<br/>' . t('It is recommended to install the !countdown module, and enable the option in !link to show the time left to the user.', array(
      '!link' => l('Quiz configuration', 'admin/quiz/settings/config'),
      '!countdown' => l('jquery_countdown', 'http://drupal.org/project/jquery_countdown'),
    )),
  );

  // Set up the availability options.
  $form['quiz_availability'] = array(
    '#type' => 'fieldset',
    '#title' => t('Availability options'),
    '#collapsed' => TRUE,
    '#collapsible' => TRUE,
    '#attributes' => array(
      'id' => 'availability-fieldset',
    ),
    '#group' => 'additional_settings',
  );
  $form['quiz_availability']['quiz_always'] = array(
    '#type' => 'checkbox',
    '#title' => t('Always available'),
    '#default_value' => $node->quiz_always,
    '#description' => t('Ignore the open and close dates.'),
    '#disabled' => !module_exists('date_popup'),
  );
  if (module_exists('date_popup')) {
    $format = 'Y-m-d H:i';
    $form['quiz_availability']['quiz_open'] = array(
      '#type' => 'date_popup',
      '#title' => t('Open date'),
      '#default_value' => date($format, $node->quiz_open ? $node->quiz_open : REQUEST_TIME),
      '#description' => t('The date this @quiz will become available.', array(
        '@quiz' => QUIZ_NAME,
      )),
    );
    $form['quiz_availability']['quiz_close'] = array(
      '#type' => 'date_popup',
      '#title' => t('Close date'),
      '#default_value' => date($format, $node->quiz_close ? $node->quiz_close : REQUEST_TIME + variable_get('quiz_default_close', 30) * 86400),
      '#description' => t('The date this @quiz will become unavailable.', array(
        '@quiz' => QUIZ_NAME,
      )),
    );
  }
  else {
    $form['quiz_availability']['help']['#markup'] = t('Enable the Date Popup (date_popup) module from the !date project to enable support for open and close dates.', array(
      '!date' => l('Date', 'http://drupal.org/project/date'),
    ));
  }

  // Quiz summary options.
  $form['summaryoptions'] = array(
    '#type' => 'fieldset',
    '#title' => t('Pass/fail options'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#attributes' => array(
      'id' => 'summaryoptions-fieldset',
    ),
    '#group' => 'additional_settings',
  );

  // If pass/fail option is checked, present the form elements.
  if (variable_get('quiz_use_passfail', 1)) {
    $form['summaryoptions']['pass_rate'] = array(
      '#type' => 'textfield',
      '#title' => t('Passing rate for @quiz (%)', array(
        '@quiz' => QUIZ_NAME,
      )),
      '#default_value' => $node->pass_rate,
      '#description' => t('Passing rate for this @quiz as a percentage score.', array(
        '@quiz' => QUIZ_NAME,
      )),
      '#required' => FALSE,
    );
    $form['summaryoptions']['summary_pass'] = array(
      '#type' => 'text_format',
      '#base_type' => 'textarea',
      '#title' => t('Summary text if passed'),
      '#default_value' => $node->summary_pass,
      '#cols' => 60,
      '#description' => t('Summary text for when the user passes the @quiz. Leave blank to not give summary text if passed, or if not using the "passing rate" field above. If not using the "passing rate" field above, this text will not be used.', array(
        '@quiz' => QUIZ_NAME,
      )),
      '#format' => isset($node->summary_pass_format) && !empty($node->summary_pass_format) ? $node->summary_pass_format : NULL,
    );
  }
  else {

    // If the pass/fail option is unchecked, use the default and hide it.
    $form['summaryoptions']['#access'] = FALSE;
  }

  // We use a helper to enable the wysiwyg module to add an editor to the
  // textarea.
  $form['summaryoptions']['helper']['summary_default'] = array(
    '#type' => 'text_format',
    '#base_type' => 'textarea',
    '#title' => t('Summary text if failed'),
    '#default_value' => $node->summary_default,
    '#cols' => 60,
    '#description' => t('Summary text for when the user fails the @quiz. Leave blank to not give summary text if failed, or if not using the "passing rate" field above. If not using the "passing rate" field above, this text will not be used.', array(
      '@quiz' => QUIZ_NAME,
    )),
    '#format' => isset($node->summary_default_format) && !empty($node->summary_default_format) ? $node->summary_default_format : NULL,
  );
  if (module_exists('token')) {

    // Embed token help.
    $form['summaryoptions']['tokens'] = array(
      '#theme' => 'token_tree_link',
      '#token_types' => array(
        'global',
        'node',
        'user',
        'quiz_result',
      ),
    );
  }

  // Number of random questions, max score and tid for random questions are set
  // on the manage questions tab. We repeat them here so that they're not
  // removed if the quiz is being updated.
  $num_rand = isset($node->number_of_random_questions) ? $node->number_of_random_questions : 0;
  $form['number_of_random_questions'] = array(
    '#type' => 'value',
    '#value' => $num_rand,
  );
  $max_score_for_random = isset($node->max_score_for_random) ? $node->max_score_for_random : 0;
  $form['max_score_for_random'] = array(
    '#type' => 'value',
    '#value' => $max_score_for_random,
  );
  $options = !empty($node->resultoptions) ? $node->resultoptions : array();
  $num_options = max(count($options), variable_get('quiz_max_result_options', 5));
  $form['resultoptions'] = array(
    '#type' => 'fieldset',
    '#title' => t('Result feedback'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#tree' => TRUE,
    '#attributes' => array(
      'id' => 'resultoptions-fieldset',
    ),
    '#group' => 'additional_settings',
  );
  if ($num_options > 0) {
    for ($i = 0; $i < $num_options; $i++) {

      // Grab each option in the array.
      $option = count($options) > 0 ? array_shift($options) : NULL;
      $form['resultoptions'][$i] = array(
        '#type' => 'fieldset',
        '#title' => t('Result option') . ' ' . ($i + 1),
        '#collapsible' => TRUE,
        '#collapsed' => FALSE,
      );
      $form['resultoptions'][$i]['option_name'] = array(
        '#type' => 'textfield',
        '#title' => t('Range title'),
        '#default_value' => isset($option['option_name']) ? $option['option_name'] : '',
        '#maxlength' => 40,
        '#size' => 40,
        '#description' => t('e.g., "A" or "Passed"'),
      );
      $form['resultoptions'][$i]['option_start'] = array(
        '#type' => 'textfield',
        '#title' => t('Percentage low'),
        '#description' => t('Show this result for scored @quiz in this range (0-100).', array(
          '@quiz' => QUIZ_NAME,
        )),
        '#default_value' => isset($option['option_start']) ? $option['option_start'] : '',
        '#size' => 5,
      );
      $form['resultoptions'][$i]['option_end'] = array(
        '#type' => 'textfield',
        '#title' => t('Percentage high'),
        '#description' => t('Show this result for scored @quiz in this range (0-100).', array(
          '@quiz' => QUIZ_NAME,
        )),
        '#default_value' => isset($option['option_end']) ? $option['option_end'] : '',
        '#size' => 5,
      );
      $form['resultoptions'][$i]['option_summary'] = array(
        '#type' => 'text_format',
        '#base_type' => 'textarea',
        '#title' => t('Feedback'),
        '#default_value' => isset($option['option_summary']) ? $option['option_summary'] : '',
        '#description' => t("This is the text that will be displayed when the user's score falls in this range."),
        '#format' => isset($option['option_summary_format']) ? $option['option_summary_format'] : NULL,
      );
      if (isset($option['option_id'])) {
        $form['resultoptions'][$i]['option_id'] = array(
          '#type' => 'hidden',
          '#value' => isset($option['option_id']) ? $option['option_id'] : '',
        );
      }
    }
    if (module_exists('token')) {

      // Embed token help.
      $form['resultoptions']['tokens'] = array(
        '#theme' => 'token_tree_link',
        '#token_types' => array(
          'global',
          'node',
          'user',
          'quiz_result',
        ),
      );
    }
  }
  $form['remember_settings'] = array(
    '#type' => 'checkbox',
    '#title' => t('Remember my settings'),
    '#description' => t('If this box is checked most of the @quiz specific settings you have made will be remembered and will be your default settings next time you create a @quiz.', array(
      '@quiz' => QUIZ_NAME,
    )),
    '#weight' => 49,
  );
  $form['remember_global'] = array(
    '#type' => 'checkbox',
    '#title' => t('Remember as global'),
    '#description' => t("If this box is checked most of the @quiz specific settings you have made will be remembered and will be everyone's default settings next time they create a @quiz.", array(
      '@quiz' => QUIZ_NAME,
    )),
    '#weight' => 49,
    '#access' => user_access('administer quiz configuration'),
  );
  if (quiz_has_been_answered($node) && variable_get('quiz_auto_revisioning', 1)) {
    $node->revision = 1;
    $node->log = t('The current revision has been answered. We create a new revision so that the reports from the existing answers stays correct.');
  }
  return $form;
}