1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once 'Modules/Test/interfaces/interface.ilTestQuestionSequence.php';
5require_once 'Modules/Test/interfaces/interface.ilTestSequenceSummaryProvider.php';
6
7/**
8* Test sequence handler
9*
10* This class manages the sequence settings for a given user
11*
12* @author		Helmut Schottmüller <helmut.schottmueller@mac.com>
13* @version	$Id$
14* @ingroup ModulesTest
15*/
16class ilTestSequence implements ilTestQuestionSequence, ilTestSequenceSummaryProvider
17{
18    /**
19    * An array containing the sequence data
20    *
21    * @var array
22    */
23    public $sequencedata;
24
25    /**
26    * The mapping of the sequence numbers to the questions
27    *
28    * @var array
29    */
30    public $questions;
31
32    /**
33    * The active id of the sequence data
34    *
35    * @var integer
36    */
37    public $active_id;
38
39    /**
40    * The pass of the current sequence
41    *
42    * @var integer
43    */
44    public $pass;
45
46    /**
47    * Indicates wheather the active test is a random test or not
48    *
49    * @var boolean
50    */
51    public $isRandomTest;
52
53    /**
54     * @var integer[]
55     */
56    protected $alreadyPresentedQuestions = array();
57
58    /**
59     * @var int
60     */
61    protected $newlyPresentedQuestion = 0;
62
63    /**
64     * @var array
65     */
66    protected $alreadyCheckedQuestions;
67
68    /**
69     * @var integer
70     */
71    protected $newlyCheckedQuestion;
72
73    /**
74     * @var array
75     */
76    protected $optionalQuestions;
77
78    /**
79     * @var bool
80     */
81    private $answeringOptionalQuestionsConfirmed;
82
83    /**
84     * @var bool
85     */
86    private $considerHiddenQuestionsEnabled;
87
88    /**
89     * @var bool
90     */
91    private $considerOptionalQuestionsEnabled;
92
93    /**
94    * ilTestSequence constructor
95    *
96    * The constructor takes possible arguments an creates an instance of
97    * the ilTestSequence object.
98    *
99    * @param object $a_object A reference to the test container object
100    * @access public
101    */
102    public function __construct($active_id, $pass, $randomtest)
103    {
104        $this->active_id = $active_id;
105        $this->pass = $pass;
106        $this->isRandomTest = $randomtest;
107        $this->sequencedata = array(
108            "sequence" => array(),
109            "postponed" => array(),
110            "hidden" => array()
111        );
112
113        $this->alreadyCheckedQuestions = array();
114        $this->newlyCheckedQuestion = null;
115
116        $this->optionalQuestions = array();
117        $this->answeringOptionalQuestionsConfirmed = false;
118
119        $this->considerHiddenQuestionsEnabled = false;
120        $this->considerOptionalQuestionsEnabled = true;
121    }
122
123    public function getActiveId()
124    {
125        return $this->active_id;
126    }
127
128    public function createNewSequence($max, $shuffle)
129    {
130        $newsequence = array();
131        if ($max > 0) {
132            for ($i = 1; $i <= $max; $i++) {
133                array_push($newsequence, $i);
134            }
135            if ($shuffle) {
136                $newsequence = $this->pcArrayShuffle($newsequence);
137            }
138        }
139        $this->sequencedata["sequence"] = $newsequence;
140    }
141
142    /**
143    * Loads the question mapping
144    */
145    public function loadQuestions(ilTestQuestionSetConfig $testQuestionSetConfig = null, $taxonomyFilterSelection = array())
146    {
147        global $DIC;
148        $ilDB = $DIC['ilDB'];
149
150        $this->questions = array();
151
152        $result = $ilDB->queryF(
153            "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",
154            array('integer'),
155            array($this->active_id)
156        );
157
158        $index = 1;
159
160        // TODO bheyser: There might be "sequence" gaps which lead to issues with tst_sequence when deleting/adding questions before any participant starts the test
161        while ($data = $ilDB->fetchAssoc($result)) {
162            $this->questions[$index++] = $data["question_fi"];
163        }
164    }
165
166    /**
167    * Loads the sequence data for a given active id
168    *
169    * @return string The filesystem path of the certificate
170    */
171    public function loadFromDb()
172    {
173        $this->loadQuestionSequence();
174        $this->loadPresentedQuestions();
175        $this->loadCheckedQuestions();
176        $this->loadOptionalQuestions();
177    }
178
179    private function loadQuestionSequence()
180    {
181        global $DIC;
182        $ilDB = $DIC['ilDB'];
183        $result = $ilDB->queryF(
184            "SELECT * FROM tst_sequence WHERE active_fi = %s AND pass = %s",
185            array('integer','integer'),
186            array($this->active_id, $this->pass)
187        );
188        if ($result->numRows()) {
189            $row = $ilDB->fetchAssoc($result);
190            $this->sequencedata = array(
191                "sequence" => unserialize($row["sequence"]),
192                "postponed" => unserialize($row["postponed"]),
193                "hidden" => unserialize($row["hidden"])
194            );
195            if (!is_array($this->sequencedata["sequence"])) {
196                $this->sequencedata["sequence"] = array();
197            }
198            if (!is_array($this->sequencedata["postponed"])) {
199                $this->sequencedata["postponed"] = array();
200            }
201            if (!is_array($this->sequencedata["hidden"])) {
202                $this->sequencedata["hidden"] = array();
203            }
204
205            $this->setAnsweringOptionalQuestionsConfirmed((bool) $row['ans_opt_confirmed']);
206        }
207    }
208
209    protected function loadPresentedQuestions()
210    {
211        global $DIC; /* @var ILIAS\DI\Container $DIC */
212
213        $res = $DIC->database()->queryF(
214            "SELECT question_fi FROM tst_seq_qst_presented WHERE active_fi = %s AND pass = %s",
215            array('integer','integer'),
216            array($this->active_id, $this->pass)
217        );
218
219        while ($row = $DIC->database()->fetchAssoc($res)) {
220            $this->alreadyPresentedQuestions[ $row['question_fi'] ] = $row['question_fi'];
221        }
222    }
223
224    private function loadCheckedQuestions()
225    {
226        global $DIC;
227        $ilDB = $DIC['ilDB'];
228
229        $res = $ilDB->queryF(
230            "SELECT question_fi FROM tst_seq_qst_checked WHERE active_fi = %s AND pass = %s",
231            array('integer','integer'),
232            array($this->active_id, $this->pass)
233        );
234
235        while ($row = $ilDB->fetchAssoc($res)) {
236            $this->alreadyCheckedQuestions[ $row['question_fi'] ] = $row['question_fi'];
237        }
238    }
239
240    private function loadOptionalQuestions()
241    {
242        global $DIC;
243        $ilDB = $DIC['ilDB'];
244
245        $res = $ilDB->queryF(
246            "SELECT question_fi FROM tst_seq_qst_optional WHERE active_fi = %s AND pass = %s",
247            array('integer','integer'),
248            array($this->active_id, $this->pass)
249        );
250
251        while ($row = $ilDB->fetchAssoc($res)) {
252            $this->optionalQuestions[ $row['question_fi'] ] = $row['question_fi'];
253        }
254    }
255
256    /**
257    * Saves the sequence data for a given pass to the database
258    *
259    * @access public
260    */
261    public function saveToDb()
262    {
263        $this->saveQuestionSequence();
264        $this->saveNewlyPresentedQuestion();
265        $this->saveNewlyCheckedQuestion();
266        $this->saveOptionalQuestions();
267    }
268
269    private function saveQuestionSequence()
270    {
271        global $DIC;
272        $ilDB = $DIC['ilDB'];
273
274        $postponed = null;
275        if ((is_array($this->sequencedata["postponed"])) && (count($this->sequencedata["postponed"]))) {
276            $postponed = serialize($this->sequencedata["postponed"]);
277        }
278        $hidden = null;
279        if ((is_array($this->sequencedata["hidden"])) && (count($this->sequencedata["hidden"]))) {
280            $hidden = serialize($this->sequencedata["hidden"]);
281        }
282
283        $affectedRows = $ilDB->manipulateF(
284            "DELETE FROM tst_sequence WHERE active_fi = %s AND pass = %s",
285            array('integer','integer'),
286            array($this->active_id, $this->pass)
287        );
288
289        $affectedRows = $ilDB->insert("tst_sequence", array(
290            "active_fi" => array("integer", $this->active_id),
291            "pass" => array("integer", $this->pass),
292            "sequence" => array("clob", serialize($this->sequencedata["sequence"])),
293            "postponed" => array("text", $postponed),
294            "hidden" => array("text", $hidden),
295            "tstamp" => array("integer", time()),
296            'ans_opt_confirmed' => array('integer', (int) $this->isAnsweringOptionalQuestionsConfirmed())
297        ));
298    }
299
300    protected function saveNewlyPresentedQuestion()
301    {
302        if ((int) $this->newlyPresentedQuestion) {
303            global $DIC; /* @var ILIAS\DI\Container $DIC */
304
305            $DIC->database()->replace('tst_seq_qst_presented', array(
306                'active_fi' => array('integer', (int) $this->active_id),
307                'pass' => array('integer', (int) $this->pass),
308                'question_fi' => array('integer', (int) $this->newlyPresentedQuestion)
309            ), array());
310        }
311    }
312
313    /**
314     * @global ilDBInterface $ilDB
315     */
316    private function saveNewlyCheckedQuestion()
317    {
318        if ((int) $this->newlyCheckedQuestion) {
319            global $DIC;
320            $ilDB = $DIC['ilDB'];
321
322            $ilDB->replace('tst_seq_qst_checked', array(
323                'active_fi' => array('integer', (int) $this->active_id),
324                'pass' => array('integer', (int) $this->pass),
325                'question_fi' => array('integer', (int) $this->newlyCheckedQuestion)
326            ), array());
327        }
328    }
329
330    /**
331     * @global ilDBInterface $ilDB
332     */
333    private function saveOptionalQuestions()
334    {
335        global $DIC;
336        $ilDB = $DIC['ilDB'];
337
338        $NOT_IN_questions = $ilDB->in('question_fi', $this->optionalQuestions, true, 'integer');
339
340        $ilDB->queryF(
341            "DELETE FROM tst_seq_qst_optional WHERE active_fi = %s AND pass = %s AND $NOT_IN_questions",
342            array('integer', 'integer'),
343            array($this->active_id, $this->pass)
344        );
345
346        foreach ($this->optionalQuestions as $questionId) {
347            $ilDB->replace('tst_seq_qst_optional', array(
348                'active_fi' => array('integer', (int) $this->active_id),
349                'pass' => array('integer', (int) $this->pass),
350                'question_fi' => array('integer', (int) $questionId)
351            ), array());
352        }
353    }
354
355    public function postponeQuestion($question_id)
356    {
357        if (!$this->isPostponedQuestion($question_id)) {
358            array_push($this->sequencedata["postponed"], intval($question_id));
359        }
360    }
361
362    public function hideQuestion($question_id)
363    {
364        if (!$this->isHiddenQuestion($question_id)) {
365            array_push($this->sequencedata["hidden"], intval($question_id));
366        }
367    }
368
369    public function isPostponedQuestion($question_id)
370    {
371        if (!is_array($this->sequencedata["postponed"])) {
372            return false;
373        }
374        if (!in_array($question_id, $this->sequencedata["postponed"])) {
375            return false;
376        } else {
377            return true;
378        }
379    }
380
381    public function isHiddenQuestion($question_id)
382    {
383        if (!is_array($this->sequencedata["hidden"])) {
384            return false;
385        }
386        if (!in_array($question_id, $this->sequencedata["hidden"])) {
387            return false;
388        } else {
389            return true;
390        }
391    }
392
393    public function isPostponedSequence($sequence)
394    {
395        if (!array_key_exists($sequence, $this->questions)) {
396            return false;
397        }
398        if (!is_array($this->sequencedata["postponed"])) {
399            return false;
400        }
401        if (!in_array($this->questions[$sequence], $this->sequencedata["postponed"])) {
402            return false;
403        } else {
404            return true;
405        }
406    }
407
408    public function isHiddenSequence($sequence)
409    {
410        if (!array_key_exists($sequence, $this->questions)) {
411            return false;
412        }
413        if (!is_array($this->sequencedata["hidden"])) {
414            return false;
415        }
416        if (!in_array($this->questions[$sequence], $this->sequencedata["hidden"])) {
417            return false;
418        } else {
419            return true;
420        }
421    }
422
423    public function postponeSequence($sequence)
424    {
425        if (!$this->isPostponedSequence($sequence)) {
426            if (array_key_exists($sequence, $this->questions)) {
427                if (!is_array($this->sequencedata["postponed"])) {
428                    $this->sequencedata["postponed"] = array();
429                }
430                array_push($this->sequencedata["postponed"], intval($this->questions[$sequence]));
431            }
432        }
433    }
434
435    public function hideSequence($sequence)
436    {
437        if (!$this->isHiddenSequence($sequence)) {
438            if (array_key_exists($sequence, $this->questions)) {
439                if (!is_array($this->sequencedata["hidden"])) {
440                    $this->sequencedata["hidden"] = array();
441                }
442                array_push($this->sequencedata["hidden"], intval($this->questions[$sequence]));
443            }
444        }
445    }
446
447    public function setQuestionPresented($questionId)
448    {
449        $this->newlyPresentedQuestion = $questionId;
450    }
451
452    public function isQuestionPresented($questionId)
453    {
454        return (
455            $this->newlyPresentedQuestion == $questionId || in_array($questionId, $this->alreadyPresentedQuestions)
456        );
457    }
458
459    public function isNextQuestionPresented($questionId)
460    {
461        $nextQstId = $this->getQuestionForSequence(
462            $this->getNextSequence($this->getSequenceForQuestion($questionId))
463        );
464
465        if (!$nextQstId) {
466            return false;
467        }
468
469        if ($this->newlyPresentedQuestion == $nextQstId) {
470            return true;
471        }
472
473        if (in_array($nextQstId, $this->alreadyPresentedQuestions)) {
474            return true;
475        }
476
477        return false;
478    }
479
480    public function setQuestionChecked($questionId)
481    {
482        $this->newlyCheckedQuestion = $questionId;
483    }
484
485    public function isQuestionChecked($questionId)
486    {
487        return isset($this->alreadyCheckedQuestions[$questionId]);
488    }
489
490    public function getPositionOfSequence($sequence)
491    {
492        $correctedsequence = $this->getCorrectedSequence();
493        $sequencekey = array_search($sequence, $correctedsequence);
494        if ($sequencekey !== false) {
495            return $sequencekey + 1;
496        } else {
497            return "";
498        }
499    }
500
501    public function getUserQuestionCount()
502    {
503        return count($this->getCorrectedSequence());
504    }
505
506    public function getOrderedSequence()
507    {
508        $sequenceKeys = array();
509
510        foreach (array_keys($this->questions) as $sequenceKey) {
511            if ($this->isHiddenSequence($sequenceKey) && !$this->isConsiderHiddenQuestionsEnabled()) {
512                continue;
513            }
514
515            if ($this->isSequenceOptional($sequenceKey) && !$this->isConsiderOptionalQuestionsEnabled()) {
516                continue;
517            }
518
519            $sequenceKeys[] = $sequenceKey;
520        }
521
522        return $sequenceKeys;
523    }
524
525    public function getOrderedSequenceQuestions()
526    {
527        $questions = array();
528
529        foreach ($this->questions as $questionId) {
530            if ($this->isHiddenQuestion($questionId) && !$this->isConsiderHiddenQuestionsEnabled()) {
531                continue;
532            }
533
534            if ($this->isQuestionOptional($questionId) && !$this->isConsiderOptionalQuestionsEnabled()) {
535                continue;
536            }
537
538            $questions[] = $questionId;
539        }
540
541        return $questions;
542    }
543
544    public function getUserSequence()
545    {
546        return $this->getCorrectedSequence();
547    }
548
549    public function getUserSequenceQuestions()
550    {
551        $seq = $this->getCorrectedSequence();
552        $found = array();
553        foreach ($seq as $sequence) {
554            array_push($found, $this->getQuestionForSequence($sequence));
555        }
556        return $found;
557    }
558
559    private function ensureQuestionNotInSequence($sequence, $questionId)
560    {
561        $questionKey = array_search($questionId, $this->questions);
562
563        if ($questionKey === false) {
564            return $sequence;
565        }
566
567        $sequenceKey = array_search($questionKey, $sequence);
568
569        if ($sequenceKey === false) {
570            return $sequence;
571        }
572
573        unset($sequence[$sequenceKey]);
574
575        return $sequence;
576    }
577
578    protected function getCorrectedSequence()
579    {
580        $correctedsequence = $this->sequencedata["sequence"];
581        if (!$this->isConsiderHiddenQuestionsEnabled()) {
582            if (is_array($this->sequencedata["hidden"])) {
583                foreach ($this->sequencedata["hidden"] as $question_id) {
584                    $correctedsequence = $this->ensureQuestionNotInSequence($correctedsequence, $question_id);
585                }
586            }
587        }
588        if (!$this->isConsiderOptionalQuestionsEnabled()) {
589            foreach ($this->optionalQuestions as $questionId) {
590                $correctedsequence = $this->ensureQuestionNotInSequence($correctedsequence, $questionId);
591            }
592        }
593        if (is_array($this->sequencedata["postponed"])) {
594            foreach ($this->sequencedata["postponed"] as $question_id) {
595                $foundsequence = array_search($question_id, $this->questions);
596                if ($foundsequence !== false) {
597                    $sequencekey = array_search($foundsequence, $correctedsequence);
598                    if ($sequencekey !== false) {
599                        unset($correctedsequence[$sequencekey]);
600                        array_push($correctedsequence, $foundsequence);
601                    }
602                }
603            }
604        }
605        return array_values($correctedsequence);
606    }
607
608    public function getSequenceForQuestion($question_id)
609    {
610        return array_search($question_id, $this->questions);
611    }
612
613    public function getFirstSequence()
614    {
615        $correctedsequence = $this->getCorrectedSequence();
616        if (count($correctedsequence)) {
617            return reset($correctedsequence);
618        } else {
619            return false;
620        }
621    }
622
623    public function getLastSequence()
624    {
625        $correctedsequence = $this->getCorrectedSequence();
626        if (count($correctedsequence)) {
627            return end($correctedsequence);
628        } else {
629            return false;
630        }
631    }
632
633    public function getNextSequence($sequence)
634    {
635        $correctedsequence = $this->getCorrectedSequence();
636        $sequencekey = array_search($sequence, $correctedsequence);
637        if ($sequencekey !== false) {
638            $nextsequencekey = $sequencekey + 1;
639            if (array_key_exists($nextsequencekey, $correctedsequence)) {
640                return $correctedsequence[$nextsequencekey];
641            }
642        }
643        return false;
644    }
645
646    public function getPreviousSequence($sequence)
647    {
648        $correctedsequence = $this->getCorrectedSequence();
649        $sequencekey = array_search($sequence, $correctedsequence);
650        if ($sequencekey !== false) {
651            $prevsequencekey = $sequencekey - 1;
652            if (($prevsequencekey >= 0) && (array_key_exists($prevsequencekey, $correctedsequence))) {
653                return $correctedsequence[$prevsequencekey];
654            }
655        }
656        return false;
657    }
658
659    /**
660    * Shuffles the values of a given array
661    *
662    * Shuffles the values of a given array
663    *
664    * @param array $array An array which should be shuffled
665    * @access public
666    */
667    public function pcArrayShuffle($array)
668    {
669        $keys = array_keys($array);
670        shuffle($keys);
671        $result = array();
672        foreach ($keys as $key) {
673            $result[$key] = $array[$key];
674        }
675        return $result;
676    }
677
678    public function getQuestionForSequence($sequence)
679    {
680        if ($sequence < 1) {
681            return false;
682        }
683        if (array_key_exists($sequence, $this->questions)) {
684            return $this->questions[$sequence];
685        } else {
686            return false;
687        }
688    }
689
690    public function getSequenceSummary($obligationsFilterEnabled = false)
691    {
692        $correctedsequence = $this->getCorrectedSequence();
693        $result_array = array();
694        include_once "./Modules/Test/classes/class.ilObjTest.php";
695        $solved_questions = ilObjTest::_getSolvedQuestions($this->active_id);
696        $key = 1;
697        foreach ($correctedsequence as $sequence) {
698            $question = &ilObjTest::_instanciateQuestion($this->getQuestionForSequence($sequence));
699            if (is_object($question)) {
700                $worked_through = $question->_isWorkedThrough($this->active_id, $question->getId(), $this->pass);
701                $solved = 0;
702                if (array_key_exists($question->getId(), $solved_questions)) {
703                    $solved = $solved_questions[$question->getId()]["solved"];
704                }
705                $is_postponed = $this->isPostponedQuestion($question->getId());
706
707                $row = array(
708                    "nr" => "$key",
709                    "title" => $question->getTitle(),
710                    "qid" => $question->getId(),
711                    "presented" => $this->isQuestionPresented($question->getId()),
712                    "visited" => $worked_through,
713                    "solved" => (($solved)?"1":"0"),
714                    "description" => $question->getComment(),
715                    "points" => $question->getMaximumPoints(),
716                    "worked_through" => $worked_through,
717                    "postponed" => $is_postponed,
718                    "sequence" => $sequence,
719                    "obligatory" => ilObjTest::isQuestionObligatory($question->getId()),
720                    'isAnswered' => $question->isAnswered($this->active_id, $this->pass)
721                );
722
723                if (!$obligationsFilterEnabled || $row['obligatory']) {
724                    array_push($result_array, $row);
725                }
726
727                $key++;
728            }
729        }
730        return $result_array;
731    }
732
733    public function getPass()
734    {
735        return $this->pass;
736    }
737
738    public function setPass($pass)
739    {
740        $this->pass = $pass;
741    }
742
743    public function hasSequence()
744    {
745        if ((is_array($this->sequencedata["sequence"])) && (count($this->sequencedata["sequence"]) > 0)) {
746            return true;
747        } else {
748            return false;
749        }
750    }
751
752    public function hasHiddenQuestions()
753    {
754        if ((is_array($this->sequencedata["hidden"])) && (count($this->sequencedata["hidden"]) > 0)) {
755            return true;
756        } else {
757            return false;
758        }
759    }
760
761    public function clearHiddenQuestions()
762    {
763        $this->sequencedata["hidden"] = array();
764    }
765
766    private function hideCorrectAnsweredQuestions(ilObjTest $testOBJ, $activeId, $pass)
767    {
768        if ($activeId > 0) {
769            $result = $testOBJ->getTestResult($activeId, $pass, true);
770
771            foreach ($result as $sequence => $question) {
772                if (is_numeric($sequence)) {
773                    if ($question['reached'] == $question['max']) {
774                        $this->hideQuestion($question['qid']);
775                    }
776                }
777            }
778
779            $this->saveToDb();
780        }
781    }
782
783    public function hasStarted(ilTestSession $testSession)
784    {
785        if ($testSession->getLastSequence() < 1) {
786            return false;
787        }
788
789        // WTF ?? heard about tests with only one question !?
790        if ($testSession->getLastSequence() == $this->getFirstSequence()) {
791            return false;
792        }
793
794        return true;
795    }
796
797    public function openQuestionExists()
798    {
799        return $this->getFirstSequence() !== false;
800    }
801
802    public function getQuestionIds()
803    {
804        return array_values($this->questions);
805    }
806
807    public function questionExists($questionId)
808    {
809        return in_array($questionId, $this->questions);
810    }
811
812    public function setQuestionOptional($questionId)
813    {
814        $this->optionalQuestions[$questionId] = $questionId;
815    }
816
817    public function isQuestionOptional($questionId)
818    {
819        return isset($this->optionalQuestions[$questionId]);
820    }
821
822    public function hasOptionalQuestions()
823    {
824        return (bool) count($this->optionalQuestions);
825    }
826
827    public function getOptionalQuestions()
828    {
829        return $this->optionalQuestions;
830    }
831
832    public function clearOptionalQuestions()
833    {
834        $this->optionalQuestions = array();
835    }
836
837    public function reorderOptionalQuestionsToSequenceEnd()
838    {
839        $optionalSequenceKeys = array();
840
841        foreach ($this->sequencedata['sequence'] as $index => $sequenceKey) {
842            if ($this->isQuestionOptional($this->getQuestionForSequence($sequenceKey))) {
843                $optionalSequenceKeys[$index] = $sequenceKey;
844                unset($this->sequencedata['sequence'][$index]);
845            }
846        }
847
848        foreach ($optionalSequenceKeys as $index => $sequenceKey) {
849            $this->sequencedata['sequence'][$index] = $sequenceKey;
850        }
851    }
852
853    /**
854     * @return boolean
855     */
856    public function isAnsweringOptionalQuestionsConfirmed()
857    {
858        return $this->answeringOptionalQuestionsConfirmed;
859    }
860
861    /**
862     * @param boolean $answeringOptionalQuestionsConfirmed
863     */
864    public function setAnsweringOptionalQuestionsConfirmed($answeringOptionalQuestionsConfirmed)
865    {
866        $this->answeringOptionalQuestionsConfirmed = $answeringOptionalQuestionsConfirmed;
867    }
868
869    /**
870     * @return boolean
871     */
872    public function isConsiderHiddenQuestionsEnabled()
873    {
874        return $this->considerHiddenQuestionsEnabled;
875    }
876
877    /**
878     * @param boolean $considerHiddenQuestionsEnabled
879     */
880    public function setConsiderHiddenQuestionsEnabled($considerHiddenQuestionsEnabled)
881    {
882        $this->considerHiddenQuestionsEnabled = $considerHiddenQuestionsEnabled;
883    }
884
885    /**
886     * @return boolean
887     */
888    public function isConsiderOptionalQuestionsEnabled()
889    {
890        return $this->considerOptionalQuestionsEnabled;
891    }
892
893    /**
894     * @param boolean $considerOptionalQuestionsEnabled
895     */
896    public function setConsiderOptionalQuestionsEnabled($considerOptionalQuestionsEnabled)
897    {
898        $this->considerOptionalQuestionsEnabled = $considerOptionalQuestionsEnabled;
899    }
900}
901