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