You are here

public function QuizQuestion::getNodeForm in Quiz 8.4

Returns a node form to quiz_question_form

Adds default form elements, and fetches question type specific elements from their implementation of getCreationForm

Parameters

array $form_state:

Return value

unknown_type

File

question_types/quiz_question/lib/Drupal/quiz_question/QuizQuestion.php, line 89
Classes used in the Quiz Question module.

Class

QuizQuestion
A base implementation of a quiz_question, adding a layer of abstraction between the node API, quiz API and the question types.

Namespace

Drupal\quiz_question

Code

public function getNodeForm(array $form_state = NULL) {
  $user = \Drupal::currentUser();
  $form = array();

  // mark this form to be processed by quiz_form_alter. quiz_form_alter will among other things
  // hide the revion fieldset if the user don't have permission to controll the revisioning manually.
  $form['#quiz_check_revision_access'] = TRUE;

  // Allow user to set title?
  if ($user
    ->hasPermission('edit question titles')) {
    $form['helper']['#theme'] = 'quiz_question_creation_form';

    /*
    $form['title'] = array(
      '#type' => 'textfield',
      '#title' => t('Title'),
      '#maxlength' => 255,
      '#default_value' => $this->node->getTitle(),
      '#required' => FALSE,
      '#description' => t('Add a title that will help distinguish this question from other questions. This will not be seen during the quiz.'),
    );
    */
  }
  else {
    $form['title'] = array(
      '#type' => 'value',
      '#value' => $this->node
        ->getTitle(),
    );
  }

  // Quiz id used here to tie creation of a question to a specific quiz
  if (isset($_GET['quiz_nid']) && is_numeric($_GET['quiz_nid'])) {
    $vid = _quiz_is_int($_GET['quiz_vid'], 0) ? $_GET['quiz_vid'] : NULL;
    $quiz = node_load((int) $_GET['quiz_nid'], $vid);

    // Store quiz id in the form
    $form['quiz_nid'] = array(
      '#type' => 'value',
      '#value' => $quiz
        ->id(),
    );
    $form['quiz_vid'] = array(
      '#type' => 'value',
      '#value' => $quiz
        ->getRevisionId(),
    );

    // Identify this node as a quiz question type so that it can be recognized by other modules effectively.
    $form['is_quiz_question'] = array(
      '#type' => 'value',
      '#value' => TRUE,
    );

    // If coming from quiz view, go back there on submit.
    if ($quiz
      ->getType() == 'quiz') {
      $form_state['redirect'] = 'node/' . $quiz
        ->id() . '/questions';
      $form['#cancel_button'] = TRUE;
    }
  }

  //Add question type specific content
  $form = array_merge($form, $this
    ->getCreationForm($form_state));

  // If access to edit quizzes we add the add to quiz fieldset
  $edit_access = quiz_access_multi_or('edit any quiz content', 'edit own quiz content', 'administer nodes');
  if ($edit_access) {
    $own_filter = quiz_access_multi_or('edit any quiz', 'administer nodes') ? '' : 'AND n.uid = ' . intval($user
      ->id());

    // Fieldset allowing question makers to add questions to multiple quizzes when creating or editing a question
    $already = array();
    $already_nids = array();
    if ($this->node
      ->id() && is_numeric($this->node
      ->id())) {

      // Finding quizzes this question already belongs to.
      $sql = 'SELECT n.nid, r.parent_vid AS vid, nd.title FROM {quiz_node_relationship} r
                JOIN {node} n ON n.nid = r.parent_nid
                JOIN {node_field_data} nd ON nd.nid = r.parent_nid
                WHERE r.child_vid = :child_vid
                ORDER BY r.parent_vid DESC';
      $res = db_query($sql, array(
        ':child_vid' => $this->node
          ->getRevisionId(),
      ));

      // Store the results
      while ($res_o = $res
        ->fetch()) {
        if (in_array($res_o->nid, $already_nids)) {
          continue;
        }

        // Store in simple array to use in later querries
        $already_nids[] = $res_o->nid;

        // Store in array to use as #options
        $already[$res_o->nid . '-' . $res_o->vid] = check_plain($res_o->title);
      }
    }
    $found = implode(', ', $already_nids);
    $latest = array();
    $latest_nids = array();

    // Finding the last quizzes the current user has been using
    $sql = "SELECT lq.quiz_nid, n.vid, nd.title, lq.id FROM {quiz_question_latest_quizzes} lq\n              JOIN {node} n ON n.nid = lq.quiz_nid\n              JOIN {node_field_data} nd ON nd.nid = lq.quiz_nid AND n.vid = nd.vid\n              JOIN {quiz_node_properties} qnp ON qnp.vid = n.vid\n              WHERE lq.uid = :uid AND qnp.randomization < 3";
    if (drupal_strlen($found) > 0) {
      $sql .= " AND quiz_nid NOT IN ({$found})";
    }
    $sql .= " ORDER BY lq.id DESC";

    // TODO Please convert this statement to the D7 database API syntax.
    $res = db_query($sql, array(
      ':uid' => $user
        ->id(),
    ));
    while ($res_o = $res
      ->fetch()) {

      // Array to use as #option in form element
      $latest[$res_o->quiz_nid . '-' . $res_o->vid] = check_plain($res_o->title);

      // Array to use in later queries
      $latest_nids[] = $res_o->quiz_nid;
    }
    if (count($latest) < QUIZ_QUESTION_NUM_LATEST) {

      // Suplementing with other available quizzes...
      $found = implode(', ', array_merge($already_nids, $latest_nids));
      $sql = "SELECT n.nid, n.vid, nd.title, changed FROM {node} n\n        \t\tJOIN {quiz_node_properties} qnp ON qnp.vid = n.vid\n        \t\tJOIN {node_field_data} nd ON nd.vid = n.vid AND n.vid = nd.vid\n                WHERE nd.type = 'quiz' AND qnp.randomization < 3";
      if (drupal_strlen($found) > 0) {
        $sql .= " AND n.nid NOT IN ({$found})";
      }

      //$sql .= " ORDER BY changed LIMIT %d";

      // TODO Please convert this statement to the D7 database API syntax.

      //$res = db_query(db_rewrite_sql($sql), QUIZ_QUESTION_NUM_LATEST - count($latest));
      $res = db_query($sql);
      while ($res_o = $res
        ->fetch()) {

        // array to be used as #options in form element
        $latest[$res_o->nid . '-' . $res_o->vid] = check_plain($res_o->title);
      }
    }

    // If we came from the manage questions tab we need to mark the quiz we came from as selected.
    $latest_default = array();
    if (isset($quiz)) {
      foreach ($latest as $key => $value) {
        $latest_nid = preg_match('/^[0-9]+/', $key);
        if ($latest_nid == $quiz
          ->id()) {
          unset($latest[$key]);
          break;
        }
      }
      $res = db_query('SELECT title FROM {node_field_revision} WHERE vid = :vid', array(
        ':vid' => $quiz
          ->getRevisionId(),
      ));
      $latest[$quiz
        ->id() . '-' . $quiz
        ->getRevisionId()] = check_plain($res
        ->fetchField());

      // $latest_default is to be used as #default_value in form item
      $latest_default[] = $quiz
        ->id() . '-' . $quiz
        ->getRevisionId();
    }
  }
  if ($edit_access || quiz_access_multi_or('create quiz content', 'administer nodes')) {
    $form['add_directly'] = array(
      '#type' => 'fieldset',
      '#title' => t('Add to @quiz', array(
        '@quiz' => QUIZ_NAME,
      )),
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#weight' => -3,
      '#tree' => TRUE,
      '#group' => 'additional_settings',
    );
  }
  if ($edit_access) {
    if (count($already) > 0) {
      $form['add_directly']['already'] = array(
        '#type' => 'checkboxes',
        '#title' => t('This question is already a member of'),
        '#description' => t('If you uncheck any of the checkboxes this question will be removed from the corresponding @quiz. If the @quiz has been answered a new revision of the @quiz will be created automatically.', array(
          '@quiz' => QUIZ_NAME,
        )),
        '#options' => $already,
        '#default_value' => array_keys($already),
      );
    }
    if (count($latest) > 0) {
      $form['add_directly']['latest'] = array(
        '#type' => 'checkboxes',
        '#title' => t('The @latest latest @quiz nodes this question isn\'t a member of', array(
          '@latest' => count($latest),
          '@quiz' => QUIZ_NAME,
        )),
        '#description' => t('If you check any of the checkboxes this question will be added to the corresponding @quiz. If the @quiz has been answered a new revision will be created automatically.', array(
          '@quiz' => QUIZ_NAME,
        )),
        '#options' => $latest,
        '#default_value' => $latest_default,
      );
    }
  }
  if (quiz_access_multi_or('create quiz content', 'administer nodes')) {
    $form['add_directly']['new'] = array(
      '#type' => 'textfield',
      '#title' => t('Title for new @quiz', array(
        '@quiz' => QUIZ_NAME,
      )),
      '#description' => t('Write in the name of the new @quiz you want to create and add this question to.', array(
        '@quiz' => QUIZ_NAME,
      )),
    );
  }
  if ($this
    ->hasBeenAnswered()) {
    $log = t('The current revision has been answered. We create a new revision so that the reports from the existing answers stays correct.');
    $this->node->revision = 1;
    $this->node->log = $log;
  }
  return $form;
}