/** * Get all the usable questions from a particular question category. * * @param int $categoryid the id of a question category. * @param bool whether to include questions from subcategories. * @param string $questionsinuse comma-separated list of question ids to * exclude from consideration. * @return array of question records. */ public function get_available_questions_from_category($categoryid, $subcategories) { if (isset($this->availablequestionsbycategory[$categoryid][$subcategories])) { return $this->availablequestionsbycategory[$categoryid][$subcategories]; } $this->init_qtype_lists(); if ($subcategories) { $categoryids = question_categorylist($categoryid); } else { $categoryids = array($categoryid); } $questionids = question_bank::get_finder()->get_questions_from_categories( $categoryids, 'qtype NOT IN (' . $this->excludedqtypes . ')'); $this->availablequestionsbycategory[$categoryid][$subcategories] = $questionids; return $questionids; }
/** * Get all the usable shortanswer questions from a particular question category. * * @param integer $categoryid the id of a question category. * @param bool $subcategories whether to include questions from subcategories. * @return array of question records. */ public function get_available_saquestions_from_category($categoryid, $subcategories) { if (isset($this->availablesaquestionsbycategory[$categoryid][$subcategories])) { return $this->availablesaquestionsbycategory[$categoryid][$subcategories]; } if ($subcategories) { $categoryids = question_categorylist($categoryid); } else { $categoryids = array($categoryid); } $questionids = question_bank::get_finder()->get_questions_from_categories($categoryids, "qtype = 'shortanswer'"); $this->availablesaquestionsbycategory[$categoryid][$subcategories] = $questionids; return $questionids; }
public function test_get_questions_from_categories_with_usage_counts() { $this->resetAfterTest(); $generator = $this->getDataGenerator()->get_plugin_generator('core_question'); $cat = $generator->create_question_category(); $questiondata1 = $generator->create_question('shortanswer', null, array('category' => $cat->id)); $questiondata2 = $generator->create_question('shortanswer', null, array('category' => $cat->id)); $questiondata3 = $generator->create_question('shortanswer', null, array('category' => $cat->id)); $quba = question_engine::make_questions_usage_by_activity('test', context_system::instance()); $quba->set_preferred_behaviour('deferredfeedback'); $question1 = question_bank::load_question($questiondata1->id); $question3 = question_bank::load_question($questiondata3->id); $quba->add_question($question1); $quba->add_question($question1); $quba->add_question($question3); $quba->start_all_questions(); question_engine::save_questions_usage_by_activity($quba); $this->assertEquals(array($questiondata2->id => 0, $questiondata3->id => 1, $questiondata1->id => 2), question_bank::get_finder()->get_questions_from_categories_with_usage_counts(array($cat->id), new qubaid_list(array($quba->get_id())))); }
/** * Populate {@link $availablequestionscache} for this combination of options. * @param int $categoryid the id of a category in the question bank. * @param bool $includesubcategories wether to pick a question from exactly * that category, or that category and subcategories. */ protected function ensure_questions_for_category_loaded($categoryid, $includesubcategories) { global $DB; $categorykey = $this->get_category_key($categoryid, $includesubcategories); if (isset($this->availablequestionscache[$categorykey])) { // Data is already in the cache, nothing to do. return; } // Load the available questions from the question bank. if ($includesubcategories) { $categoryids = question_categorylist($categoryid); } else { $categoryids = array($categoryid); } list($extraconditions, $extraparams) = $DB->get_in_or_equal($this->excludedqtypes, SQL_PARAMS_NAMED, 'excludedqtype', false); $questionidsandcounts = \question_bank::get_finder()->get_questions_from_categories_with_usage_counts($categoryids, $this->qubaids, 'q.qtype ' . $extraconditions, $extraparams); if (!$questionidsandcounts) { // No questions in this category. $this->availablequestionscache[$categorykey] = array(); return; } // Put all the questions with each value of $prevusecount in separate arrays. $idsbyusecount = array(); foreach ($questionidsandcounts as $questionid => $prevusecount) { if (isset($this->recentlyusedquestions[$questionid])) { // Recently used questions are never returned. continue; } $idsbyusecount[$prevusecount][] = $questionid; } // Now put that data into our cache. For each count, we need to shuffle // questionids, and make those the keys of an array. $this->availablequestionscache[$categorykey] = array(); foreach ($idsbyusecount as $prevusecount => $questionids) { shuffle($questionids); $this->availablequestionscache[$categorykey][$prevusecount] = array_combine($questionids, array_fill(0, count($questionids), 1)); } ksort($this->availablequestionscache[$categorykey]); }