1<?php 2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssQuestionType.php'; 5 6/** 7 * Handles a list of questions 8 * 9 * @author Björn Heyser <bheyser@databay.de> 10 * @version $Id$ 11 * 12 * @package Modules/TestQuestionPool 13 * 14 */ 15class ilTestRandomQuestionSetStagingPoolQuestionList implements Iterator 16{ 17 /** 18 * @var ilDBInterface 19 */ 20 private $db = null; 21 22 /** 23 * @var ilPluginAdmin 24 */ 25 private $pluginAdmin = null; 26 27 /** 28 * @var integer 29 */ 30 private $testObjId = -1; 31 32 /** 33 * @var integer 34 */ 35 private $testId = -1; 36 37 /** 38 * @var integer 39 */ 40 private $poolId = -1; 41 42 /** 43 * @var array 44 */ 45 private $taxFilters = array(); 46 47 // fau: taxFilter/typeFilter - private variable 48 // TODO-RND2017: rename to typesFilter (multiple types allowed) 49 /** 50 * @var array 51 */ 52 private $typeFilter = array(); 53 // fau. 54 55 /** 56 * @var array 57 */ 58 private $lifecycleFilter = array(); 59 60 /** 61 * @var array 62 */ 63 private $questions = array(); 64 65 /** 66 * @param ilDB $db 67 * @param ilPluginAdmin $pluginAdmin 68 */ 69 public function __construct(ilDBInterface $db, ilPluginAdmin $pluginAdmin) 70 { 71 $this->db = $db; 72 $this->pluginAdmin = $pluginAdmin; 73 } 74 75 public function setTestObjId($testObjId) 76 { 77 $this->testObjId = $testObjId; 78 } 79 80 public function getTestObjId() 81 { 82 return $this->testObjId; 83 } 84 85 public function setTestId($testId) 86 { 87 $this->testId = $testId; 88 } 89 90 public function getTestId() 91 { 92 return $this->testId; 93 } 94 95 public function setPoolId($poolId) 96 { 97 $this->poolId = $poolId; 98 } 99 100 public function getPoolId() 101 { 102 return $this->poolId; 103 } 104 105 public function addTaxonomyFilter($taxId, $taxNodes) 106 { 107 $this->taxFilters[$taxId] = $taxNodes; 108 } 109 110 public function getTaxonomyFilters() 111 { 112 return $this->taxFilters; 113 } 114 115 // fau: taxFilter/typeFilter - getter/setter 116 public function getTypeFilter() 117 { 118 return $this->typeFilter; 119 } 120 121 public function setTypeFilter($typeFilter) 122 { 123 $this->typeFilter = $typeFilter; 124 } 125 // fau. 126 127 /** 128 * @return array 129 */ 130 public function getLifecycleFilter() : array 131 { 132 return $this->lifecycleFilter; 133 } 134 135 /** 136 * @param array $lifecycleFilter 137 */ 138 public function setLifecycleFilter(array $lifecycleFilter) 139 { 140 $this->lifecycleFilter = $lifecycleFilter; 141 } 142 143 public function loadQuestions() 144 { 145 $query = " 146 SELECT qpl_questions.question_id, 147 qpl_qst_type.type_tag, 148 qpl_qst_type.plugin, 149 qpl_qst_type.plugin_name 150 151 FROM tst_rnd_cpy 152 153 INNER JOIN qpl_questions 154 ON qpl_questions.question_id = tst_rnd_cpy.qst_fi 155 156 INNER JOIN qpl_qst_type 157 ON qpl_qst_type.question_type_id = qpl_questions.question_type_fi 158 159 WHERE tst_rnd_cpy.tst_fi = %s 160 AND tst_rnd_cpy.qpl_fi = %s 161 162 {$this->getConditionalExpression()} 163 "; 164 165 $res = $this->db->queryF( 166 $query, 167 array('integer', 'integer'), 168 array($this->getTestId(), $this->getPoolId()) 169 ); 170 171 //echo sprintf($query, $this->getTestId(), $this->getPoolId());exit; 172 173 while ($row = $this->db->fetchAssoc($res)) { 174 $row = ilAssQuestionType::completeMissingPluginName($row); 175 176 if (!$this->isActiveQuestionType($row)) { 177 continue; 178 } 179 180 $this->questions[] = $row['question_id']; 181 } 182 } 183 184 private function getConditionalExpression() 185 { 186 $CONDITIONS = $this->getTaxonomyFilterExpressions(); 187 188 // fau: taxFilter/typeFilter - add the type filter expression to conditions 189 $CONDITIONS = array_merge($CONDITIONS, $this->getTypeFilterExpressions()); 190 // fau. 191 192 $CONDITIONS = array_merge($CONDITIONS, $this->getLifecycleFilterExpressions()); 193 194 $CONDITIONS = implode(' AND ', $CONDITIONS); 195 196 return strlen($CONDITIONS) ? 'AND ' . $CONDITIONS : ''; 197 } 198 199 private function getTaxonomyFilterExpressions() 200 { 201 $expressions = array(); 202 203 require_once 'Services/Taxonomy/classes/class.ilTaxonomyTree.php'; 204 require_once 'Services/Taxonomy/classes/class.ilTaxNodeAssignment.php'; 205 206 foreach ($this->getTaxonomyFilters() as $taxId => $taxNodes) { 207 $questionIds = array(); 208 209 $forceBypass = true; 210 211 foreach ($taxNodes as $taxNode) { 212 $forceBypass = false; 213 214 $taxTree = new ilTaxonomyTree($taxId); 215 216 $taxNodeAssignment = new ilTaxNodeAssignment('tst', $this->getTestObjId(), 'quest', $taxId); 217 218 $subNodes = $taxTree->getSubTreeIds($taxNode); 219 $subNodes[] = $taxNode; 220 221 $taxItems = $taxNodeAssignment->getAssignmentsOfNode($subNodes); 222 223 foreach ($taxItems as $taxItem) { 224 $questionIds[$taxItem['item_id']] = $taxItem['item_id']; 225 } 226 } 227 228 if (!$forceBypass) { 229 $expressions[] = $this->db->in('question_id', $questionIds, false, 'integer'); 230 } 231 } 232 233 return $expressions; 234 } 235 236 private function getLifecycleFilterExpressions() 237 { 238 if (count($this->lifecycleFilter)) { 239 return array( 240 $this->db->in('lifecycle', $this->lifecycleFilter, false, 'text') 241 ); 242 } 243 244 return array(); 245 } 246 247 // fau: taxFilter/typeFilter - get the expressions for a type filter 248 private function getTypeFilterExpressions() 249 { 250 if (count($this->typeFilter)) { 251 return array( 252 $this->db->in('question_type_fi', $this->typeFilter, false, 'integer') 253 ); 254 } 255 256 return array(); 257 } 258 // fau; 259 260 private function isActiveQuestionType($questionData) 261 { 262 if (!isset($questionData['plugin'])) { 263 return false; 264 } 265 266 if (!$questionData['plugin']) { 267 return true; 268 } 269 270 return $this->pluginAdmin->isActive(IL_COMP_MODULE, 'TestQuestionPool', 'qst', $questionData['plugin_name']); 271 } 272 273 public function resetQuestionList() 274 { 275 $this->questions = array(); 276 $this->taxFilters = array(); 277 278 $this->testObjId = -1; 279 $this->testId = -1; 280 $this->poolId = -1; 281 } 282 283 public function getQuestions() 284 { 285 return array_values($this->questions); 286 } 287 288 // ================================================================================================================= 289 290 /** 291 * @return ilTestRandomQuestionSetSourcePoolDefinition 292 */ 293 public function rewind() 294 { 295 return reset($this->questions); 296 } 297 298 /** 299 * @return ilTestRandomQuestionSetSourcePoolDefinition 300 */ 301 public function current() 302 { 303 return current($this->questions); 304 } 305 306 /** 307 * @return integer 308 */ 309 public function key() 310 { 311 return key($this->questions); 312 } 313 314 /** 315 * @return ilTestRandomQuestionSetSourcePoolDefinition 316 */ 317 public function next() 318 { 319 return next($this->questions); 320 } 321 322 /** 323 * @return boolean 324 */ 325 public function valid() 326 { 327 return key($this->questions) !== null; 328 } 329 330 public static function updateSourceQuestionPoolId($testId, $oldPoolId, $newPoolId) 331 { 332 $db = $GLOBALS['DIC']['ilDB']; 333 334 $query = "UPDATE tst_rnd_cpy SET qpl_fi = %s WHERE tst_fi = %s AND qpl_fi = %s"; 335 336 $db->manipulateF( 337 $query, 338 array('integer', 'integer', 'integer'), 339 array($newPoolId, $testId, $oldPoolId) 340 ); 341 } 342} 343