/** * Add a relation between question and category in table c_quiz_question_rel_category * @param int $categoryId * @param int $questionId * @param int $courseId * * @return int */ public static function add_category_for_question_id($categoryId, $questionId, $courseId) { $table = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY); // if question doesn't have a category // @todo change for 1.10 when a question can have several categories if (TestCategory::getCategoryForQuestion($questionId, $courseId) == 0 && $questionId > 0 && $courseId > 0) { $sql = "INSERT INTO {$table} (c_id, question_id, category_id)\n VALUES (" . intval($courseId) . ", " . intval($questionId) . ", " . intval($categoryId) . ")"; Database::query($sql); $id = Database::insert_id(); return $id; } return false; }
/** * Calculate the max_score of the quiz, depending of question inside, and quiz advanced option */ public function get_max_score() { $out_max_score = 0; $tab_question_list = $this->selectQuestionList(true); // list of question's id !!! the array key start at 1 !!! // test is randomQuestions - see field random of test if ($this->random > 0 && $this->randomByCat == 0) { $nb_random_questions = $this->random; $tab_questions_score = array(); for ($i = 1; $i <= count($tab_question_list); $i++) { $tmpobj_question = Question::read($tab_question_list[$i]); $tab_questions_score[] = $tmpobj_question->weighting; } rsort($tab_questions_score); // add the first $nb_random_questions value of score array to get max_score for ($i = 0; $i < min($nb_random_questions, count($tab_questions_score)); $i++) { $out_max_score += $tab_questions_score[$i]; } } else { if ($this->random > 0 && $this->randomByCat > 0) { $nb_random_questions = $this->random; $tab_categories_scores = array(); for ($i = 1; $i <= count($tab_question_list); $i++) { $question_category_id = TestCategory::getCategoryForQuestion($tab_question_list[$i]); if (!is_array($tab_categories_scores[$question_category_id])) { $tab_categories_scores[$question_category_id] = array(); } $tmpobj_question = Question::read($tab_question_list[$i]); $tab_categories_scores[$question_category_id][] = $tmpobj_question->weighting; } // here we've got an array with first key, the category_id, second key, score of question for this cat while (list($key, $tab_scores) = each($tab_categories_scores)) { rsort($tab_scores); for ($i = 0; $i < min($nb_random_questions, count($tab_scores)); $i++) { $out_max_score += $tab_scores[$i]; } } } else { for ($i = 1; $i <= count($tab_question_list); $i++) { $tmpobj_question = Question::read($tab_question_list[$i]); $out_max_score += $tmpobj_question->weighting; } } } return $out_max_score; }
$my_exercise->read($exercise['id']); if (!empty($my_exercise)) { if (!empty($my_exercise->questionList)) { foreach ($my_exercise->questionList as $question_id) { $question_obj = Question::read($question_id, $courseItemId); if ($exerciseLevel != '-1') { if ($exerciseLevel != $question_obj->level) { continue; } } if ($answerType > 0) { if ($answerType != $question_obj->type) { continue; } } $categoryIdFromQuestion = TestCategory::getCategoryForQuestion($question_obj->id, $selected_course); if ($courseCategoryId > 0 && $categoryIdFromQuestion != $courseCategoryId) { continue; } if (!empty($objExercise) && $objExercise->feedback_type != EXERCISE_FEEDBACK_TYPE_DIRECT) { if ($question_obj->type == HOT_SPOT_DELINEATION) { continue; } } $question_row = array('id' => $question_obj->id, 'question' => $question_obj->question, 'type' => $question_obj->type, 'level' => $question_obj->level, 'exercise_id' => $exercise['id'], 'exercise_name' => $exercise['title'], 'course_id' => $courseItemId); $mainQuestionList[] = $question_row; } } } } }
/** * Build the Quiz-Questions * @param int $courseId Internal course ID */ public function build_quiz_questions($courseId = 0) { $table_qui = Database::get_course_table(TABLE_QUIZ_TEST); $table_rel = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION); $table_que = Database::get_course_table(TABLE_QUIZ_QUESTION); $table_ans = Database::get_course_table(TABLE_QUIZ_ANSWER); // Building normal tests. $sql = "SELECT * FROM {$table_que}\n WHERE c_id = {$courseId} "; $result = Database::query($sql); while ($obj = Database::fetch_object($result)) { // find the question category // @todo : need to be adapted for multi category questions in 1.10 $question_category_id = TestCategory::getCategoryForQuestion($obj->id, $courseId); // build the backup resource question object $question = new QuizQuestion($obj->id, $obj->question, $obj->description, $obj->ponderation, $obj->type, $obj->position, $obj->picture, $obj->level, $obj->extra, $question_category_id); $sql = 'SELECT * FROM ' . $table_ans . ' WHERE c_id = ' . $courseId . ' AND question_id = ' . $obj->id; $db_result2 = Database::query($sql); while ($obj2 = Database::fetch_object($db_result2)) { $question->add_answer($obj2->id, $obj2->answer, $obj2->correct, $obj2->comment, $obj2->ponderation, $obj2->position, $obj2->hotspot_coordinates, $obj2->hotspot_type); if ($obj->type == MULTIPLE_ANSWER_TRUE_FALSE) { $table_options = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION); $sql = 'SELECT * FROM ' . $table_options . ' WHERE c_id = ' . $courseId . ' AND question_id = ' . $obj->id; $db_result3 = Database::query($sql); while ($obj3 = Database::fetch_object($db_result3)) { $question_option = new QuizQuestionOption($obj3); $question->add_option($question_option); } } } $this->course->add_resource($question); } // Building a fictional test for collecting orphan questions. // When a course is emptied this option should be activated (true). $build_orphan_questions = !empty($_POST['recycle_option']); // 1st union gets the orphan questions from deleted exercises // 2nd union gets the orphan questions from question that were deleted in a exercise. $sql = " (\n SELECT question_id, q.* FROM {$table_que} q INNER JOIN {$table_rel} r\n ON (q.c_id = r.c_id AND q.id = r.question_id)\n INNER JOIN {$table_qui} ex\n ON (ex.id = r.exercice_id AND ex.c_id = r.c_id )\n WHERE ex.c_id = {$courseId} AND ex.active = '-1'\n )\n UNION\n (\n SELECT question_id, q.* FROM {$table_que} q left\n OUTER JOIN {$table_rel} r\n ON (q.c_id = r.c_id AND q.id = r.question_id)\n WHERE q.c_id = {$courseId} AND r.question_id is null\n )\n UNION\n (\n SELECT question_id, q.* FROM {$table_que} q\n INNER JOIN {$table_rel} r\n ON (q.c_id = r.c_id AND q.id = r.question_id)\n WHERE r.c_id = {$courseId} AND (r.exercice_id = '-1' OR r.exercice_id = '0')\n )\n "; $result = Database::query($sql); if (Database::num_rows($result) > 0) { $build_orphan_questions = true; $orphanQuestionIds = array(); while ($obj = Database::fetch_object($result)) { // Orphan questions if (!empty($obj->question_id)) { $obj->id = $obj->question_id; } // Avoid adding the same question twice if (!isset($this->course->resources[$obj->id])) { // find the question category // @todo : need to be adapted for multi category questions in 1.10 $question_category_id = TestCategory::getCategoryForQuestion($obj->id, $courseId); $question = new QuizQuestion($obj->id, $obj->question, $obj->description, $obj->ponderation, $obj->type, $obj->position, $obj->picture, $obj->level, $obj->extra, $question_category_id); $sql = "SELECT * FROM {$table_ans}\n WHERE c_id = {$courseId} AND question_id = " . $obj->id; $db_result2 = Database::query($sql); if (Database::num_rows($db_result2)) { while ($obj2 = Database::fetch_object($db_result2)) { $question->add_answer($obj2->id, $obj2->answer, $obj2->correct, $obj2->comment, $obj2->ponderation, $obj2->position, $obj2->hotspot_coordinates, $obj2->hotspot_type); } $orphanQuestionIds[] = $obj->id; } $this->course->add_resource($question); } } } if ($build_orphan_questions) { $obj = array('id' => -1, 'title' => get_lang('OrphanQuestions', ''), 'type' => 2); $newQuiz = new Quiz((object) $obj); if (!empty($orphanQuestionIds)) { foreach ($orphanQuestionIds as $index => $orphanId) { $order = $index + 1; $newQuiz->add_question($orphanId, $order); } } $this->course->add_resource($newQuiz); } }
/** * Reads question information from the data base * * @param int $id - question ID * @param int $course_id * * @return Question * * @author Olivier Brouckaert */ public static function read($id, $course_id = null) { $id = intval($id); if (!empty($course_id)) { $course_info = api_get_course_info_by_id($course_id); } else { $course_info = api_get_course_info(); } $course_id = $course_info['real_id']; if (empty($course_id) || $course_id == -1) { return false; } $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION); $TBL_EXERCISE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION); $sql = "SELECT question, description, ponderation, position, type, picture, level, extra\n FROM {$TBL_QUESTIONS}\n WHERE c_id = {$course_id} AND id = {$id} "; $result = Database::query($sql); // if the question has been found if ($object = Database::fetch_object($result)) { $objQuestion = Question::getInstance($object->type); if (!empty($objQuestion)) { $objQuestion->id = $id; $objQuestion->question = $object->question; $objQuestion->description = $object->description; $objQuestion->weighting = $object->ponderation; $objQuestion->position = $object->position; $objQuestion->type = $object->type; $objQuestion->picture = $object->picture; $objQuestion->level = (int) $object->level; $objQuestion->extra = $object->extra; $objQuestion->course = $course_info; $objQuestion->category = TestCategory::getCategoryForQuestion($id); $tblQuiz = Database::get_course_table(TABLE_QUIZ_TEST); $sql = "SELECT DISTINCT q.exercice_id\n FROM {$TBL_EXERCISE_QUESTION} q\n INNER JOIN {$tblQuiz} e\n ON e.c_id = q.c_id AND e.id = q.exercice_id\n WHERE\n q.c_id = {$course_id} AND\n q.question_id = {$id} AND\n e.active >= 0"; $result = Database::query($sql); // fills the array with the exercises which this question is in if ($result) { while ($obj = Database::fetch_object($result)) { $objQuestion->exerciseList[] = $obj->exercice_id; } } return $objQuestion; } } // question not found return false; }
/** * Add a relation between question and category in table c_quiz_question_rel_category * @param int $in_category_id * @param int $in_question_id * @param int $in_course_c_id */ public static function add_category_for_question_id($in_category_id, $in_question_id, $in_course_c_id) { $tbl_reltable = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY); // if question doesn't have a category // @todo change for 1.10 when a question can have several categories if (TestCategory::getCategoryForQuestion($in_question_id, $in_course_c_id) == 0 && $in_question_id > 0 && $in_course_c_id > 0) { $sql = "INSERT INTO {$tbl_reltable}\n VALUES (" . intval($in_course_c_id) . ", " . intval($in_question_id) . ", " . intval($in_category_id) . ")"; Database::query($sql); } }