1<?php 2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetQuestion.php'; 5 6/** 7 * @author Björn Heyser <bheyser@databay.de> 8 * @version $Id$ 9 * 10 * @package Modules/Test 11 */ 12// hey: fixRandomTestBuildable - iterator interface for collection 13class ilTestRandomQuestionSetQuestionCollection implements 14 Iterator 15// hey. 16{ 17 private $questions = array(); 18 19 public function setQuestions($questions) 20 { 21 $this->questions = $questions; 22 } 23 24 public function getQuestions() 25 { 26 return $this->questions; 27 } 28 29 public function addQuestion(ilTestRandomQuestionSetQuestion $question) 30 { 31 $this->questions[] = $question; 32 } 33 34 // hey: fixRandomTestBuildable - iterator interface for collection 35 /* @return ilTestRandomQuestionSetQuestion */ 36 public function current() 37 { 38 return current($this->questions); 39 } 40 /* @return ilTestRandomQuestionSetQuestion */ 41 public function next() 42 { 43 return next($this->questions); 44 } 45 /* @return string */ 46 public function key() 47 { 48 return key($this->questions); 49 } 50 /* @return bool */ 51 public function valid() 52 { 53 return key($this->questions) !== null; 54 } 55 /* @return ilTestRandomQuestionSetQuestion */ 56 public function rewind() 57 { 58 return reset($this->questions); 59 } 60 // hey. 61 62 public function isGreaterThan($amount) 63 { 64 return count($this->questions) > $amount; 65 } 66 67 public function isSmallerThan($amount) 68 { 69 return count($this->questions) < $amount; 70 } 71 72 /** 73 * @param int $requiredAmount 74 * @return int 75 */ 76 public function getMissingCount($requiredAmount) 77 { 78 // hey: fixRandomTestBuildable - fix returning missing count instead of difference (neg values!) 79 $difference = $requiredAmount - count($this->questions); 80 $missingCount = $difference < 0 ? 0 : $difference; 81 return $missingCount; 82 // hey. 83 } 84 85 public function shuffleQuestions() 86 { 87 shuffle($this->questions); 88 } 89 90 public function mergeQuestionCollection(self $questionCollection) 91 { 92 $this->questions = array_merge($this->questions, $questionCollection->getQuestions()); 93 } 94 95 public function getUniqueQuestionCollection() 96 { 97 $uniqueQuestions = array(); 98 99 foreach ($this->getQuestions() as $question) { 100 /* @var ilTestRandomQuestionSetQuestion $question */ 101 102 if (!isset($uniqueQuestions[$question->getQuestionId()])) { 103 $uniqueQuestions[$question->getQuestionId()] = $question; 104 } 105 } 106 107 $uniqueQuestionCollection = new self(); 108 $uniqueQuestionCollection->setQuestions($uniqueQuestions); 109 110 return $uniqueQuestionCollection; 111 } 112 113 public function getRelativeComplementCollection(self $questionCollection) 114 { 115 // hey: fixRandomTestBuildable - comment for refactoring 116 /** 117 * actually i would like to consider $this as quantity A 118 * passed $questionCollection is should be considered as quantity B 119 * 120 * --> relative complement usually means all element from B missing in A 121 * 122 * indeed we are considering $questionCollection as A and $this as B currently (!) 123 * when changing, do not forget to switch caller and param for all usages (!) 124 */ 125 // hey. 126 127 $questionIds = array_flip($questionCollection->getInvolvedQuestionIds()); 128 129 $relativeComplementCollection = new self(); 130 131 foreach ($this->getQuestions() as $question) { 132 if (!isset($questionIds[$question->getQuestionId()])) { 133 $relativeComplementCollection->addQuestion($question); 134 } 135 } 136 137 return $relativeComplementCollection; 138 } 139 140 // hey: fixRandomTestBuildable - advanced need for quantity tools 141 /** 142 * @param ilTestRandomQuestionSetQuestionCollection $questionCollection 143 * @return ilTestRandomQuestionSetQuestionCollection 144 */ 145 public function getIntersectionCollection(self $questionCollection) 146 { 147 $questionIds = array_flip($questionCollection->getInvolvedQuestionIds()); 148 149 $intersectionCollection = new self(); 150 151 foreach ($this->getQuestions() as $question) { 152 if (!isset($questionIds[$question->getQuestionId()])) { 153 continue; 154 } 155 156 $intersectionCollection->addQuestion($question); 157 } 158 159 return $intersectionCollection; 160 } 161 162 /** 163 * @return int 164 */ 165 public function getQuestionAmount() 166 { 167 return count($this->getQuestions()); 168 } 169 // hey. 170 171 public function getInvolvedQuestionIds() 172 { 173 $questionIds = array(); 174 175 foreach ($this->getQuestions() as $question) { 176 $questionIds[] = $question->getQuestionId(); 177 } 178 179 return $questionIds; 180 } 181 182 public function getRandomQuestionCollection($requiredAmount) 183 { 184 $randomKeys = $this->getRandomArrayKeys($this->questions, $requiredAmount); 185 186 $randomQuestionCollection = new self(); 187 188 foreach ($randomKeys as $randomKey) { 189 $randomQuestionCollection->addQuestion($this->questions[$randomKey]); 190 } 191 192 return $randomQuestionCollection; 193 } 194 195 private function getRandomArrayKeys($array, $numKeys) 196 { 197 if ($numKeys < 1) { 198 return array(); 199 } 200 201 if ($numKeys > 1) { 202 return array_rand($array, $numKeys); 203 } 204 205 return array( array_rand($array, $numKeys) ); 206 } 207} 208