19 declare(strict_types=1);
68 protected int $active_id,
72 $this->sequencedata = [
81 return $this->active_id;
88 for ($i = 1; $i <= $max; $i++) {
95 $this->sequencedata[
"sequence"] = $newsequence;
103 $this->questions = [];
105 $result = $this->db->queryF(
106 "SELECT tst_test_question.* FROM tst_test_question, qpl_questions, tst_active WHERE tst_active.active_id = %s AND tst_test_question.test_fi = tst_active.test_fi AND qpl_questions.question_id = tst_test_question.question_fi ORDER BY tst_test_question.sequence",
114 while (
$data = $this->db->fetchAssoc($result)) {
115 $this->questions[$index++] =
$data[
"question_fi"];
132 $result = $this->db->queryF(
133 "SELECT * FROM tst_sequence WHERE active_fi = %s AND pass = %s",
134 [
'integer',
'integer'],
135 [$this->active_id, $this->pass]
137 if ($result->numRows()) {
138 $row = $this->db->fetchAssoc($result);
139 $this->sequencedata = [
140 "sequence" => unserialize($row[
"sequence"] ??
'', [
'allowed_classes' =>
false]),
141 "postponed" => unserialize($row[
"postponed"] ??
'', [
'allowed_classes' =>
false]),
142 "hidden" => unserialize($row[
"hidden"] ??
'', [
'allowed_classes' =>
false])
145 if (!is_array($this->sequencedata[
"sequence"])) {
146 $this->sequencedata[
"sequence"] = [];
148 if (!is_array($this->sequencedata[
"postponed"])) {
149 $this->sequencedata[
"postponed"] = [];
151 if (!is_array($this->sequencedata[
"hidden"])) {
152 $this->sequencedata[
"hidden"] = [];
161 $res = $this->db->queryF(
162 "SELECT question_fi FROM tst_seq_qst_presented WHERE active_fi = %s AND pass = %s",
163 [
'integer',
'integer'],
164 [$this->active_id, $this->pass]
167 while ($row = $this->db->fetchAssoc(
$res)) {
168 $this->alreadyPresentedQuestions[ $row[
'question_fi'] ] = $row[
'question_fi'];
174 $res = $this->db->queryF(
175 "SELECT question_fi FROM tst_seq_qst_checked WHERE active_fi = %s AND pass = %s",
176 [
'integer',
'integer'],
177 [$this->active_id, $this->pass]
180 while ($row = $this->db->fetchAssoc(
$res)) {
181 $this->alreadyCheckedQuestions[ $row[
'question_fi'] ] = $row[
'question_fi'];
187 $res = $this->db->queryF(
188 "SELECT question_fi FROM tst_seq_qst_optional WHERE active_fi = %s AND pass = %s",
189 [
'integer',
'integer'],
190 [$this->active_id, $this->pass]
193 while ($row = $this->db->fetchAssoc(
$res)) {
194 $this->optionalQuestions[ $row[
'question_fi'] ] = $row[
'question_fi'];
214 if ((is_array($this->sequencedata[
"postponed"])) && (count($this->sequencedata[
"postponed"]))) {
215 $postponed = serialize($this->sequencedata[
"postponed"]);
218 if ((is_array($this->sequencedata[
"hidden"])) && (count($this->sequencedata[
"hidden"]))) {
219 $hidden = serialize($this->sequencedata[
"hidden"]);
222 $this->db->manipulateF(
223 "DELETE FROM tst_sequence WHERE active_fi = %s AND pass = %s",
224 [
'integer',
'integer'],
225 [$this->active_id, $this->pass]
228 $this->db->insert(
"tst_sequence", [
229 "active_fi" => [
"integer", $this->active_id],
230 "pass" => [
"integer", $this->pass],
231 "sequence" => [
"clob", serialize($this->sequencedata[
"sequence"])],
232 "postponed" => [
"text", $postponed],
233 "hidden" => [
"text", $hidden],
234 "tstamp" => [
"integer", time()],
241 if ($this->newlyPresentedQuestion) {
242 $this->db->replace(
'tst_seq_qst_presented', [
243 'active_fi' => [
'integer', $this->active_id],
244 'pass' => [
'integer', $this->pass],
245 'question_fi' => [
'integer', $this->newlyPresentedQuestion]
252 if ((
int) $this->newlyCheckedQuestion) {
253 $this->db->replace(
'tst_seq_qst_checked', [
254 'active_fi' => [
'integer', $this->active_id],
255 'pass' => [
'integer', $this->pass],
256 'question_fi' => [
'integer', (
int) $this->newlyCheckedQuestion]
263 $NOT_IN_questions = $this->db->in(
'question_fi', $this->optionalQuestions,
true,
'integer');
266 "DELETE FROM tst_seq_qst_optional WHERE active_fi = %s AND pass = %s AND $NOT_IN_questions",
267 [
'integer',
'integer'],
268 [$this->active_id, $this->pass]
271 foreach ($this->optionalQuestions as $questionId) {
272 $this->db->replace(
'tst_seq_qst_optional', [
273 'active_fi' => [
'integer', $this->active_id],
274 'pass' => [
'integer', $this->pass],
275 'question_fi' => [
'integer', (
int) $questionId]
283 $this->sequencedata[
"postponed"][] = $question_id;
290 $this->sequencedata[
"hidden"][] = $question_id;
296 if (!is_array($this->sequencedata[
"postponed"])) {
299 if (!in_array($question_id, $this->sequencedata[
"postponed"])) {
308 if (!is_array($this->sequencedata[
"hidden"])) {
311 if (!in_array($question_id, $this->sequencedata[
"hidden"])) {
320 if (!array_key_exists($sequence, $this->questions)) {
323 if (!is_array($this->sequencedata[
"postponed"])) {
326 if (!in_array($this->questions[$sequence], $this->sequencedata[
"postponed"])) {
335 if (!array_key_exists($sequence, $this->questions)) {
338 if (!is_array($this->sequencedata[
"hidden"])) {
341 if (!in_array($this->questions[$sequence], $this->sequencedata[
"hidden"])) {
350 if (array_key_exists($sequence, $this->questions)) {
351 if (!is_array($this->sequencedata[
"postponed"])) {
352 $this->sequencedata[
"postponed"] = [];
354 $this->sequencedata[
"postponed"][] = (
int) $this->questions[$sequence];
362 if (array_key_exists($sequence, $this->questions)) {
363 if (!is_array($this->sequencedata[
"hidden"])) {
364 $this->sequencedata[
"hidden"] = [];
366 $this->sequencedata[
"hidden"][] = (
int) $this->questions[$sequence];
373 $this->newlyPresentedQuestion = $question_id;
379 $this->newlyPresentedQuestion == $question_id || in_array($question_id, $this->alreadyPresentedQuestions)
389 if ($next_question_id ===
null) {
393 if ($this->newlyPresentedQuestion === $next_question_id) {
397 if (in_array($next_question_id, $this->alreadyPresentedQuestions)) {
406 $this->newlyCheckedQuestion = $question_id;
411 return isset($this->alreadyCheckedQuestions[$question_id]);
417 $sequence_key = array_search($sequence, $corrected_sequence);
418 if ($sequence_key !==
false) {
419 return $sequence_key + 1;
433 foreach (array_keys($this->questions) as $sequenceKey) {
438 $sequenceKeys[] = $sequenceKey;
441 return $sequenceKeys;
448 foreach ($this->questions as $questionId) {
457 $questions[] = $questionId;
472 foreach ($seq as $sequence) {
480 $question_key = array_search($question_id, $this->questions);
482 if ($question_key ===
false) {
486 $sequence_key = array_search($question_key, $sequence);
488 if ($sequence_key ===
false) {
492 unset($sequence[$sequence_key]);
499 $corrected_sequence = $this->sequencedata[
"sequence"];
501 && is_array($this->sequencedata[
"hidden"])) {
502 foreach ($this->sequencedata[
"hidden"] as $question_id) {
507 foreach ($this->optionalQuestions as $question_id) {
511 if (is_array($this->sequencedata[
"postponed"])) {
512 foreach ($this->sequencedata[
"postponed"] as $question_id) {
513 $found_sequence = array_search($question_id, $this->questions);
514 if ($found_sequence ===
false) {
517 $sequence_key = array_search($found_sequence, $corrected_sequence);
518 if ($sequence_key !==
false) {
519 unset($corrected_sequence[$sequence_key]);
520 $corrected_sequence[] = $found_sequence;
524 return array_values($corrected_sequence);
529 return array_search($question_id, $this->questions) ?:
null;
535 if (count($correctedsequence)) {
536 return reset($correctedsequence);
545 if (count($correctedsequence)) {
546 return end($correctedsequence);
555 $sequence_key = array_search($sequence, $corrected_sequence);
556 if ($sequence_key !==
false) {
557 $next_sequence_key = $sequence_key + 1;
558 if (array_key_exists($next_sequence_key, $corrected_sequence)) {
559 return $corrected_sequence[$next_sequence_key];
568 $sequencekey = array_search($sequence, $correctedsequence);
569 if ($sequencekey !==
false) {
570 $prevsequencekey = $sequencekey - 1;
571 if (($prevsequencekey >= 0) && (array_key_exists($prevsequencekey, $correctedsequence))) {
572 return $correctedsequence[$prevsequencekey];
584 $keys = array_keys($array);
587 foreach ($keys as $key) {
588 $result[$key] = $array[$key];
598 if (array_key_exists($sequence, $this->questions)) {
599 return $this->questions[$sequence];
611 foreach ($correctedsequence as $sequence) {
613 if (is_object($question)) {
614 $worked_through = $this->questionrepository->lookupResultRecordExist($this->active_id, $question->getId(), $this->pass);
616 if (array_key_exists($question->getId(), $solved_questions)) {
617 $solved = $solved_questions[$question->getId()][
"solved"];
623 'title' => $question->getTitleForHTMLOutput(),
624 'qid' => $question->getId(),
626 'visited' => $worked_through,
627 'solved' => (($solved) ?
"1" :
"0"),
628 'description' => $question->getComment(),
629 'points' => $question->getMaximumPoints(),
630 'worked_through' => $worked_through,
631 'postponed' => $is_postponed,
632 'sequence' => $sequence,
633 'isAnswered' => $question->isAnswered($this->active_id, $this->pass),
634 'has_authorized_answer' => $question->authorizedSolutionExists($this->active_id, $this->pass)
640 return $result_array;
655 if ((is_array($this->sequencedata[
"sequence"])) && (count($this->sequencedata[
"sequence"]) > 0)) {
664 if ((is_array($this->sequencedata[
"hidden"])) && (count($this->sequencedata[
"hidden"]) > 0)) {
673 $this->sequencedata[
"hidden"] = [];
697 return array_values($this->questions);
702 return in_array($question_id, $this->questions);
714 $this->optionalQuestions[$question_id] = $question_id;
719 return isset($this->optionalQuestions[$question_id]);
724 return (
bool) count($this->optionalQuestions);
734 $this->optionalQuestions = [];
739 $optionalSequenceKeys = [];
741 foreach ($this->sequencedata[
'sequence'] as $index => $sequenceKey) {
743 $optionalSequenceKeys[$index] = $sequenceKey;
744 unset($this->sequencedata[
'sequence'][$index]);
748 foreach ($optionalSequenceKeys as $index => $sequenceKey) {
749 $this->sequencedata[
'sequence'][$index] = $sequenceKey;
loadFromDb()
Loads the sequence data for a given active id.
bool $answeringOptionalQuestionsConfirmed
hideQuestion(int $question_id)
setConsiderHiddenQuestionsEnabled(bool $considerHiddenQuestionsEnabled)
bool $considerHiddenQuestionsEnabled
postponeQuestion(int $question_id)
isConsiderOptionalQuestionsEnabled()
getPositionOfSequence(int $sequence)
getQuestionForSequence(int $sequence)
getSequenceForQuestion(int $question_id)
isPostponedQuestion(int $question_id)
int $newlyPresentedQuestion
isHiddenQuestion(int $question_id)
array $questions
The mapping of the sequence numbers to the questions.
getPreviousSequence(int $sequence)
isPostponedSequence(int $sequence)
saveNewlyPresentedQuestion()
getUserSequenceQuestions()
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
setQuestionPresented(int $question_id)
saveToDb()
Saves the sequence data for a given pass to the database.
setConsiderOptionalQuestionsEnabled(bool $considerOptionalQuestionsEnabled)
pcArrayShuffle(array $array)
Shuffles the values of a given array.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setAnsweringOptionalQuestionsConfirmed(bool $answeringOptionalQuestionsConfirmed)
static instantiateQuestion(int $question_id)
isHiddenSequence(int $sequence)
setQuestionOptional(int $question_id)
hasStarted(ilTestSession $testSession)
bool $considerOptionalQuestionsEnabled
isConsiderHiddenQuestionsEnabled()
isQuestionPresented(int $question_id)
isNextQuestionPresented(int $question_id)
static _getSolvedQuestions($active_id, $question_fi=null)
get solved questions
getOrderedSequenceQuestions()
ensureQuestionNotInSequence(array $sequence, int $question_id)
array $alreadyPresentedQuestions
questionExists(int $question_id)
reorderOptionalQuestionsToSequenceEnd()
isQuestionChecked(int $question_id)
array $sequencedata
An array containing the sequence data.
saveNewlyCheckedQuestion()
postponeSequence(int $sequence)
hideSequence(int $sequence)
setQuestionChecked(int $question_id)
__construct(protected ilDBInterface $db, protected int $active_id, protected int $pass, protected GeneralQuestionPropertiesRepository $questionrepository)
ilTestSequence constructor
getNextSequence(int $sequence)
isAnsweringOptionalQuestionsConfirmed()
isQuestionOptional(int $question_id)
loadQuestions()
Loads the question mapping.
int $newlyCheckedQuestion
array $alreadyCheckedQuestions
createNewSequence(int $max, bool $shuffle)