1<?php 2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionList.php'; 5 6/** 7 * Class manages access to the dynamic question set 8 * provided for the current test 9 * 10 * @author Björn Heyser <bheyser@databay.de> 11 * @version $Id$ 12 * 13 * @package Modules/Test 14 */ 15class ilTestDynamicQuestionSet 16{ 17 /** 18 * @var ilDBInterface 19 */ 20 private $db = null; 21 22 /** 23 * @var ilLanguage 24 */ 25 private $lng = null; 26 27 /** 28 * @var ilPluginAdmin 29 */ 30 private $pluginAdmin = null; 31 32 /** 33 * @var ilObjTest 34 */ 35 private $testOBJ = null; 36 37 /** 38 * @var ilAssQuestionList 39 */ 40 private $completeQuestionList = null; 41 42 /** 43 * @var ilAssQuestionList 44 */ 45 private $selectionQuestionList = null; 46 47 /** 48 * @var ilAssQuestionList 49 */ 50 private $filteredQuestionList = null; 51 52 /** 53 * @var array 54 */ 55 private $actualQuestionSequence = array(); 56 57 /** 58 * Constructor 59 * 60 * @param ilObjTest $testOBJ 61 */ 62 public function __construct(ilDBInterface $db, ilLanguage $lng, ilPluginAdmin $pluginAdmin, ilObjTest $testOBJ) 63 { 64 $this->db = $db; 65 $this->lng = $lng; 66 $this->pluginAdmin = $pluginAdmin; 67 $this->testOBJ = $testOBJ; 68 } 69 70 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 71 72 public function load(ilObjTestDynamicQuestionSetConfig $dynamicQuestionSetConfig, ilTestDynamicQuestionSetFilterSelection $filterSelection) 73 { 74 $this->completeQuestionList = $this->initCompleteQuestionList( 75 $dynamicQuestionSetConfig, 76 $filterSelection->getAnswerStatusActiveId() 77 ); 78 79 $this->selectionQuestionList = $this->initSelectionQuestionList( 80 $dynamicQuestionSetConfig, 81 $filterSelection 82 ); 83 84 $this->filteredQuestionList = $this->initFilteredQuestionList( 85 $dynamicQuestionSetConfig, 86 $filterSelection 87 ); 88 89 $this->actualQuestionSequence = $this->initActualQuestionSequence( 90 $dynamicQuestionSetConfig, 91 $this->filteredQuestionList 92 ); 93 } 94 95 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 96 97 private function initCompleteQuestionList(ilObjTestDynamicQuestionSetConfig $dynamicQuestionSetConfig, $answerStatusActiveId) 98 { 99 $questionList = $this->buildQuestionList( 100 $dynamicQuestionSetConfig->getSourceQuestionPoolId(), 101 $answerStatusActiveId 102 ); 103 104 $questionList->load(); 105 106 return $questionList; 107 } 108 109 private function initFilteredQuestionList(ilObjTestDynamicQuestionSetConfig $dynamicQuestionSetConfig, ilTestDynamicQuestionSetFilterSelection $filterSelection) 110 { 111 $questionList = $this->buildQuestionList( 112 $dynamicQuestionSetConfig->getSourceQuestionPoolId(), 113 $filterSelection->getAnswerStatusActiveId() 114 ); 115 116 if ($dynamicQuestionSetConfig->isAnswerStatusFilterEnabled()) { 117 $questionList->setAnswerStatusFilter($filterSelection->getAnswerStatusSelection()); 118 } 119 120 if ($dynamicQuestionSetConfig->isTaxonomyFilterEnabled()) { 121 require_once 'Services/Taxonomy/classes/class.ilObjTaxonomy.php'; 122 123 $questionList->setAvailableTaxonomyIds(ilObjTaxonomy::getUsageOfObject( 124 $dynamicQuestionSetConfig->getSourceQuestionPoolId() 125 )); 126 127 foreach ($filterSelection->getTaxonomySelection() as $taxId => $taxNodes) { 128 $questionList->addTaxonomyFilter( 129 $taxId, 130 $taxNodes, 131 $this->testOBJ->getId(), 132 $this->testOBJ->getType() 133 ); 134 } 135 } elseif ($dynamicQuestionSetConfig->getOrderingTaxonomyId()) { 136 $questionList->setAvailableTaxonomyIds(array( 137 $dynamicQuestionSetConfig->getOrderingTaxonomyId() 138 )); 139 } 140 141 $questionList->setForcedQuestionIds($filterSelection->getForcedQuestionIds()); 142 143 $questionList->load(); 144 145 return $questionList; 146 } 147 148 /** 149 * @param ilObjTestDynamicQuestionSetConfig $dynamicQuestionSetConfig 150 * @param ilTestDynamicQuestionSetFilterSelection $filterSelection 151 * @return ilAssQuestionList 152 */ 153 public function initSelectionQuestionList(ilObjTestDynamicQuestionSetConfig $dynamicQuestionSetConfig, ilTestDynamicQuestionSetFilterSelection $filterSelection) 154 { 155 $questionList = $this->buildQuestionList( 156 $dynamicQuestionSetConfig->getSourceQuestionPoolId(), 157 $filterSelection->getAnswerStatusActiveId() 158 ); 159 160 if ($dynamicQuestionSetConfig->isTaxonomyFilterEnabled()) { 161 require_once 'Services/Taxonomy/classes/class.ilObjTaxonomy.php'; 162 163 $questionList->setAvailableTaxonomyIds(ilObjTaxonomy::getUsageOfObject( 164 $dynamicQuestionSetConfig->getSourceQuestionPoolId() 165 )); 166 167 foreach ($filterSelection->getTaxonomySelection() as $taxId => $taxNodes) { 168 $questionList->addTaxonomyFilter( 169 $taxId, 170 $taxNodes, 171 $this->testOBJ->getId(), 172 $this->testOBJ->getType() 173 ); 174 } 175 } 176 177 $questionList->load(); 178 179 return $questionList; 180 } 181 182 private function initActualQuestionSequence(ilObjTestDynamicQuestionSetConfig $dynamicQuestionSetConfig, ilAssQuestionList $questionList) 183 { 184 if ($dynamicQuestionSetConfig->getOrderingTaxonomyId()) { 185 return $this->getQuestionSequenceStructuredByTaxonomy( 186 $questionList, 187 $dynamicQuestionSetConfig->getOrderingTaxonomyId() 188 ); 189 } 190 191 return $this->getQuestionSequenceStructuredByUpdateDate($questionList); 192 } 193 194 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 195 196 private function getQuestionSequenceStructuredByTaxonomy(ilAssQuestionList $questionList, $orderingTaxId) 197 { 198 require_once 'Services/Taxonomy/classes/class.ilObjTaxonomy.php'; 199 $tax = new ilObjTaxonomy($orderingTaxId); 200 201 require_once 'Modules/Test/classes/class.ilTestTaxonomyTree.php'; 202 $tree = new ilTestTaxonomyTree($orderingTaxId); 203 $tree->initOrderedTreeIndex($tax); 204 205 $questionsByNode = array(); 206 $nodelessQuestions = array(); 207 208 foreach ($questionList->getQuestionDataArray() as $qId => $qData) { 209 if (isset($qData['taxonomies'][$orderingTaxId]) && count($qData['taxonomies'][$orderingTaxId])) { 210 foreach ($qData['taxonomies'][$orderingTaxId] as $nodeId => $itemData) { 211 $nodeOrderingPath = $tree->getNodeOrderingPathString($itemData['node_id']); 212 213 if (!isset($questionsByNode[ $nodeOrderingPath ])) { 214 $questionsByNode[ $nodeOrderingPath ] = array(); 215 } 216 217 if ($tax->getItemSorting() == ilObjTaxonomy::SORT_MANUAL) { 218 $questionsByNode[ $nodeOrderingPath ][$itemData['order_nr']] = $qId; 219 } else { 220 $questionsByNode[ $nodeOrderingPath ][$qData['title'] . '::' . $qId] = $qId; 221 } 222 } 223 } else { 224 $nodelessQuestions[$qData['tstamp'] . '::' . $qId] = $qId; 225 } 226 } 227 228 foreach ($questionsByNode as $path => $questions) { 229 if ($tax->getItemSorting() == ilObjTaxonomy::SORT_MANUAL) { 230 ksort($questions, SORT_NUMERIC); 231 } else { 232 ksort($questions, SORT_STRING); 233 } 234 235 $questionsByNode[$path] = array_values($questions); 236 } 237 238 ksort($questionsByNode, SORT_STRING); 239 $sequence = array_values($questionsByNode); 240 241 ksort($nodelessQuestions); 242 $sequence[] = array_values($nodelessQuestions); 243 244 return $sequence; 245 } 246 247 private function getQuestionSequenceStructuredByUpdateDate(ilAssQuestionList $questionList) 248 { 249 $sequence = array(); 250 251 foreach ($questionList->getQuestionDataArray() as $qId => $qData) { 252 $sequence[ $qData['tstamp'] . '::' . $qId ] = $qId; 253 } 254 255 ksort($sequence); 256 $sequence = array_values($sequence); 257 258 return array($sequence); 259 } 260 261 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 262 263 public function getActualQuestionSequence() 264 { 265 return $this->actualQuestionSequence; 266 } 267 268 public function questionExists($questionId) 269 { 270 $questionData = $this->completeQuestionList->getQuestionDataArray(); 271 return isset($questionData[$questionId]); 272 } 273 274 public function getQuestionData($questionId) 275 { 276 $questionData = $this->completeQuestionList->getQuestionDataArray(); 277 return $questionData[$questionId]; 278 } 279 280 public function getAllQuestionsData() 281 { 282 return $this->completeQuestionList->getQuestionDataArray(); 283 } 284 285 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 286 287 /** 288 * @return ilAssQuestionList 289 */ 290 public function getCompleteQuestionList() 291 { 292 return $this->completeQuestionList; 293 } 294 295 /** 296 * @return ilAssQuestionList 297 */ 298 public function getSelectionQuestionList() 299 { 300 return $this->selectionQuestionList; 301 } 302 303 /** 304 * @return ilAssQuestionList 305 */ 306 public function getFilteredQuestionList() 307 { 308 return $this->filteredQuestionList; 309 } 310 311 /** 312 * @param integer $sourceQuestionPoolId 313 * @param string $answerStatusActiveId 314 * @return ilAssQuestionList 315 */ 316 private function buildQuestionList($sourceQuestionPoolId, $answerStatusActiveId) 317 { 318 $questionList = new ilAssQuestionList($this->db, $this->lng, $this->pluginAdmin); 319 $questionList->setParentObjId($sourceQuestionPoolId); 320 $questionList->setAnswerStatusActiveId($answerStatusActiveId); 321 return $questionList; 322 } 323} 324