Skip to content

Commit

Permalink
MDL-20636 make syncronised datasets work for calculated* questions.
Browse files Browse the repository at this point in the history
  • Loading branch information
timhunt committed May 19, 2011
1 parent 0eb253f commit e35ba43
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 70 deletions.
2 changes: 1 addition & 1 deletion mod/quiz/startattempt.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
}

// Start all the quetsions.
$quba->start_all_questions();
$quba->start_all_questions(time(), null);

// Update attempt layout.
$newlayout = array();
Expand Down
4 changes: 3 additions & 1 deletion question/engine/questionusage.php
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,10 @@ public function start_question($slot) {

/**
* Start the attempt at all questions that has been added to this usage.
* @param int $timestamp optional, the timstamp to record for this action. Defaults to now.
* @param int $userid optional, the user to attribute this action to. Defaults to the current user.
*/
public function start_all_questions() {
public function start_all_questions($timestamp = null, $userid = null) {
foreach ($this->questionattempts as $qa) {
$qa->start($this->preferredbehaviour);
$this->observer->notify_attempt_modified($qa);
Expand Down
35 changes: 33 additions & 2 deletions question/type/calculated/question.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,19 @@
*/
class qtype_calculated_question extends qtype_numerical_question
implements qtype_calculated_question_with_expressions {

/** @var qtype_calculated_dataset_loader helper for loading the dataset. */
public $datasetloader;

/** @var qtype_calculated_variable_substituter stores the dataset we are using. */
public $vs;

/**
* @var bool wheter the dataset item to use should be chose based on attempt
* start time, rather than randomly.
*/
public $synchronised;

public function start_attempt(question_attempt_step $step) {
qtype_calculated_question_helper::start_attempt($this, $step);
parent::start_attempt($step);
Expand Down Expand Up @@ -103,9 +111,16 @@ public function calculate_all_expressions();
abstract class qtype_calculated_question_helper {
public static function start_attempt(
qtype_calculated_question_with_expressions $question, question_attempt_step $step) {

$maxnumber = $question->datasetloader->get_number_of_items();
$setnumber = rand(1, $maxnumber);
// TODO implement the $synchronizecalculated bit from create_session_and_responses.

if (!empty($question->synchronised) &&
$question->datasetloader->datasets_are_synchronised($question->category)) {

$setnumber = ($step->get_timecreated() % $maxnumber) + 1;
} else {
$setnumber = rand(1, $maxnumber);
}

$question->vs = new qtype_calculated_variable_substituter(
$question->datasetloader->get_values($setnumber),
Expand Down Expand Up @@ -211,6 +226,22 @@ public function get_values($itemnumber) {

return $this->load_values($itemnumber);
}

public function datasets_are_synchronised($category) {
global $DB;
// We need to ensure that there are synchronised datasets, and that they
// all use the right category.
$categories = $DB->get_record_sql('
SELECT MAX(qdd.category) AS max,
MIN(qdd.category) AS min
FROM {question_dataset_definitions} qdd
JOIN {question_datasets} qd ON qdd.id = qd.datasetdefinition
WHERE qd.question = ?
AND qdd.category <> 0
', array($this->questionid));

return $categories && $categories->max == $category && $categories->min == $category;
}
}


Expand Down
69 changes: 4 additions & 65 deletions question/type/calculated/questiontype.php
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,8 @@ protected function initialise_question_instance(question_definition $question, $
$question->answers[$a->id]->correctanswerformat = $a->correctanswerformat;
}

$question->synchronised = $questiondata->options->synchronize;

$question->unitdisplay = $questiondata->options->showunits;
$question->unitgradingtype = $questiondata->options->unitgradingtype;
$question->unitpenalty = $questiondata->options->unitpenalty;
Expand All @@ -362,67 +364,6 @@ protected function initialise_question_instance(question_definition $question, $
$question->datasetloader = new qtype_calculated_dataset_loader($questiondata->id);
}

public function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) {
// Find out how many datasets are available
global $CFG, $DB, $OUTPUT;
if (!$maxnumber = (int)$DB->get_field_sql(
"SELECT MIN(a.itemcount)
FROM {question_dataset_definitions} a, {question_datasets} b
WHERE b.question = ? AND a.id = b.datasetdefinition", array($question->id))) {
print_error('cannotgetdsforquestion', 'question', '', $question->id);
}

$sql = "SELECT i.*
FROM {question_datasets} d, {question_dataset_definitions} i
WHERE d.question = ? AND d.datasetdefinition = i.id AND i.category != 0";

if (!$question->options->synchronize ||
!$records = $DB->get_records_sql($sql, array($question->id))) {
$synchronizecalculated = false;
} else {
// i.e records is true so test coherence
$coherence = true;
$a = new stdClass();
$a->qid = $question->id;
$a->qcat = $question->category;
foreach ($records as $def) {
if ($def->category != $question->category) {
$a->name = $def->name;
$a->sharedcat = $def->category;
$coherence = false;
break;
}
}
if (!$coherence) {
echo $OUTPUT->notification(get_string(
'nocoherencequestionsdatyasetcategory', 'qtype_calculated', $a));
}
$synchronizecalculated = true;
}

// Choose a random dataset
// maxnumber sould not be breater than 100
if ($maxnumber > self::MAX_DATASET_ITEMS) {
$maxnumber = self::MAX_DATASET_ITEMS;
}
if ($synchronizecalculated === false) {
$state->options->datasetitem = rand(1, $maxnumber);
} else {
$state->options->datasetitem =
intval($maxnumber * substr($attempt->timestart, -2) /100);
if ($state->options->datasetitem < 1) {
$state->options->datasetitem = 1;
} else if ($state->options->datasetitem > $maxnumber) {
$state->options->datasetitem = $maxnumber;
}

};
$state->options->dataset =
$this->pick_question_dataset($question, $state->options->datasetitem);
$virtualqtype = $this->get_virtual_qtype();
return $virtualqtype->create_session_and_responses($question, $state, $cmoptions, $attempt);
}

public function validate_form($form) {
switch($form->wizardpage) {
case 'question':
Expand Down Expand Up @@ -920,8 +861,6 @@ public function get_database_dataset_items($definition) {

public function save_dataset_items($question, $fromform) {
global $CFG, $DB;
// max datasets = 100 items
$max100 = self::MAX_DATASET_ITEMS;
$synchronize = false;
if (isset($fromform->nextpageparam['forceregeneration'])) {
$regenerate = $fromform->nextpageparam['forceregeneration'];
Expand Down Expand Up @@ -997,8 +936,8 @@ public function save_dataset_items($question, $fromform) {
if (isset($fromform->addbutton) && $fromform->selectadd > 0 &&
$maxnumber < self::MAX_DATASET_ITEMS) {
$numbertoadd = $fromform->selectadd;
if ($max100 - $maxnumber < $numbertoadd) {
$numbertoadd = $max100 - $maxnumber;
if (self::MAX_DATASET_ITEMS - $maxnumber < $numbertoadd) {
$numbertoadd = self::MAX_DATASET_ITEMS - $maxnumber;
}
//add the other items.
// Generate a new dataset item (or reuse an old one)
Expand Down
14 changes: 14 additions & 0 deletions question/type/calculatedmulti/question.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,19 @@
*/
class qtype_calculatedmulti_single_question extends qtype_multichoice_single_question
implements qtype_calculated_question_with_expressions {

/** @var qtype_calculated_dataset_loader helper for loading the dataset. */
public $datasetloader;

/** @var qtype_calculated_variable_substituter stores the dataset we are using. */
public $vs;

/**
* @var bool wheter the dataset item to use should be chose based on attempt
* start time, rather than randomly.
*/
public $synchronised;

public function start_attempt(question_attempt_step $step) {
qtype_calculated_question_helper::start_attempt($this, $step);
parent::start_attempt($step);
Expand All @@ -68,12 +75,19 @@ public function calculate_all_expressions() {
*/
class qtype_calculatedmulti_multi_question extends qtype_multichoice_multi_question
implements qtype_calculated_question_with_expressions {

/** @var qtype_calculated_dataset_loader helper for loading the dataset. */
public $datasetloader;

/** @var qtype_calculated_variable_substituter stores the dataset we are using. */
public $vs;

/**
* @var bool wheter the dataset item to use should be chose based on attempt
* start time, rather than randomly.
*/
public $synchronised;

public function start_attempt(question_attempt_step $step) {
qtype_calculated_question_helper::start_attempt($this, $step);
parent::start_attempt($step);
Expand Down
2 changes: 2 additions & 0 deletions question/type/calculatedmulti/questiontype.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ protected function initialise_question_instance(question_definition $question, $
$question->layout = qtype_multichoice_single_question::LAYOUT_VERTICAL;
}

$question->synchronised = $questiondata->options->synchronize;

$this->initialise_combined_feedback($question, $questiondata, true);
$this->initialise_question_answers($question, $questiondata);

Expand Down
2 changes: 1 addition & 1 deletion question/type/questionbase.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ abstract class question_definition {
/** @var integer question category id. */
public $category;

/** @var integer question category id. */
/** @var integer question context id. */
public $contextid;

/** @var integer parent question id. */
Expand Down

0 comments on commit e35ba43

Please sign in to comment.