1<?php 2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetStagingPoolQuestionList.php'; 5require_once 'Modules/TestQuestionPool/classes/class.ilQuestionPoolFactory.php'; 6require_once 'Modules/TestQuestionPool/classes/class.assQuestion.php'; 7 8/** 9 * @author Björn Heyser <bheyser@databay.de> 10 * @version $Id$ 11 * 12 * @package Modules/Test(QuestionPool) 13 */ 14class ilTestRandomQuestionSetPoolDeriver 15{ 16 /** 17 * @var ilDBInterface 18 */ 19 protected $db; 20 21 /** 22 * @var ilPluginAdmin 23 */ 24 protected $pluginAdmin; 25 26 /** 27 * @var ilObjTest 28 */ 29 protected $testOBJ; 30 31 /** 32 * @var integer 33 */ 34 protected $targetContainerRef; 35 36 /** 37 * @var integer 38 */ 39 protected $ownerId; 40 41 /** 42 * @var ilQuestionPoolFactory 43 */ 44 protected $poolFactory; 45 46 /** 47 * @var ilTestRandomQuestionSetSourcePoolDefinitionList 48 */ 49 protected $sourcePoolDefinitionList; 50 51 public function __construct(ilDBInterface $ilDB, ilPluginAdmin $pluginAdmin, ilObjTest $testOBJ) 52 { 53 $this->db = $ilDB; 54 $this->pluginAdmin = $pluginAdmin; 55 $this->testOBJ = $testOBJ; 56 $this->poolFactory = new ilQuestionPoolFactory(); 57 } 58 59 /** 60 * @return int 61 */ 62 public function getTargetContainerRef() 63 { 64 return $this->targetContainerRef; 65 } 66 67 /** 68 * @param int $targetContainerRef 69 */ 70 public function setTargetContainerRef($targetContainerRef) 71 { 72 $this->targetContainerRef = $targetContainerRef; 73 } 74 75 /** 76 * @return int 77 */ 78 public function getOwnerId() 79 { 80 return $this->ownerId; 81 } 82 83 /** 84 * @param int $ownerId 85 */ 86 public function setOwnerId($ownerId) 87 { 88 $this->ownerId = $ownerId; 89 } 90 91 /** 92 * @return ilTestRandomQuestionSetSourcePoolDefinitionList 93 */ 94 public function getSourcePoolDefinitionList() 95 { 96 return $this->sourcePoolDefinitionList; 97 } 98 99 /** 100 * @param ilTestRandomQuestionSetSourcePoolDefinitionList $sourcePoolDefinitionList 101 */ 102 public function setSourcePoolDefinitionList($sourcePoolDefinitionList) 103 { 104 $this->sourcePoolDefinitionList = $sourcePoolDefinitionList; 105 } 106 107 protected function getQuestionsForPool(ilTestRandomQuestionSetNonAvailablePool $nonAvailablePool) 108 { 109 $questionList = new ilTestRandomQuestionSetStagingPoolQuestionList( 110 $this->db, 111 $this->pluginAdmin 112 ); 113 114 $questionList->setTestObjId($this->testOBJ->getId()); 115 $questionList->setTestId($this->testOBJ->getTestId()); 116 $questionList->setPoolId($nonAvailablePool->getId()); 117 118 $questionList->loadQuestions(); 119 120 $questions = array(); 121 122 foreach ($questionList as $questionId) { 123 $questions[] = assQuestion::_instantiateQuestion($questionId); 124 } 125 126 return $questions; 127 } 128 129 protected function createNewPool(ilTestRandomQuestionSetNonAvailablePool $nonAvailablePool) 130 { 131 $pool = $this->poolFactory->createNewInstance($this->getTargetContainerRef()); 132 133 if (strlen($nonAvailablePool->getTitle())) { 134 $pool->setTitle($nonAvailablePool->getTitle()); 135 $pool->update(); 136 } 137 138 return $pool; 139 } 140 141 protected function copyQuestionsToPool(ilObjQuestionPool $pool, $questions) 142 { 143 $poolQidByTestQidMap = array(); 144 145 foreach ($questions as $questionOBJ) { 146 /* @var assQuestion $questionOBJ */ 147 148 $testQuestionId = $questionOBJ->getId(); 149 $poolQuestionId = $questionOBJ->duplicate(false, '', '', $this->getOwnerId(), $pool->getId()); 150 151 $poolQidByTestQidMap[$testQuestionId] = $poolQuestionId; 152 } 153 154 return $poolQidByTestQidMap; 155 } 156 157 protected function updateTestQuestionStage($poolQidByTestQidMap) 158 { 159 foreach ($poolQidByTestQidMap as $testQid => $poolQid) { 160 assQuestion::resetOriginalId($poolQid); 161 assQuestion::saveOriginalId($testQid, $poolQid); 162 } 163 } 164 165 protected function filterForQuestionRelatedTaxonomies($taxonomyIds, $relatedQuestionIds) 166 { 167 require_once 'Services/Taxonomy/classes/class.ilTaxNodeAssignment.php'; 168 169 $filteredTaxIds = array(); 170 171 foreach ($taxonomyIds as $taxonomyId) { 172 $taxNodeAssignment = new ilTaxNodeAssignment( 173 $this->testOBJ->getType(), 174 $this->testOBJ->getId(), 175 'quest', 176 $taxonomyId 177 ); 178 179 foreach ($relatedQuestionIds as $questionId) { 180 $assignedTaxNodes = $taxNodeAssignment->getAssignmentsOfItem($questionId); 181 182 if (count($assignedTaxNodes)) { 183 $filteredTaxIds[] = $taxonomyId; 184 break; 185 } 186 } 187 } 188 189 return $filteredTaxIds; 190 } 191 192 protected function duplicateTaxonomies($poolQidByTestQidMap, ilObjQuestionPool $pool) 193 { 194 require_once 'Modules/TestQuestionPool/classes/class.ilQuestionPoolTaxonomiesDuplicator.php'; 195 $taxDuplicator = new ilQuestionPoolTaxonomiesDuplicator(); 196 $taxDuplicator->setSourceObjId($this->testOBJ->getId()); 197 $taxDuplicator->setSourceObjType($this->testOBJ->getType()); 198 $taxDuplicator->setTargetObjId($pool->getId()); 199 $taxDuplicator->setTargetObjType($pool->getType()); 200 $taxDuplicator->setQuestionIdMapping($poolQidByTestQidMap); 201 202 $taxDuplicator->duplicate($this->filterForQuestionRelatedTaxonomies( 203 $taxDuplicator->getAllTaxonomiesForSourceObject(), 204 array_keys($poolQidByTestQidMap) 205 )); 206 207 return $taxDuplicator->getDuplicatedTaxonomiesKeysMap(); 208 } 209 210 protected function buildOriginalTaxonomyFilterForDerivedPool(ilQuestionPoolDuplicatedTaxonomiesKeysMap $taxKeysMap, $mappedTaxonomyFilter) 211 { 212 $originalTaxonomyFilter = array(); 213 214 foreach ($mappedTaxonomyFilter as $testTaxonomyId => $testTaxNodes) { 215 $poolTaxonomyId = $taxKeysMap->getMappedTaxonomyId($testTaxonomyId); 216 $originalTaxonomyFilter[$poolTaxonomyId] = array(); 217 218 foreach ($testTaxNodes as $testTaxNode) { 219 $poolTaxNode = $taxKeysMap->getMappedTaxNodeId($testTaxNode); 220 $originalTaxonomyFilter[$poolTaxonomyId][] = $poolTaxNode; 221 } 222 } 223 224 return $originalTaxonomyFilter; 225 } 226 227 protected function updateRelatedSourcePoolDefinitions(ilQuestionPoolDuplicatedTaxonomiesKeysMap $taxKeysMap, $derivedPoolId, $nonAvailablePoolId) 228 { 229 foreach ($this->getSourcePoolDefinitionList() as $definition) { 230 if ($definition->getPoolId() != $nonAvailablePoolId) { 231 continue; 232 } 233 234 $definition->setPoolId($derivedPoolId); 235 236 $definition->setOriginalTaxonomyFilter($this->buildOriginalTaxonomyFilterForDerivedPool( 237 $taxKeysMap, 238 $definition->getMappedTaxonomyFilter() 239 )); 240 241 $definition->saveToDb(); 242 } 243 } 244 245 /** 246 * @param ilTestRandomQuestionSetNonAvailablePool $nonAvailablePool 247 * @return ilObjQuestionPool 248 */ 249 public function derive(ilTestRandomQuestionSetNonAvailablePool $nonAvailablePool) 250 { 251 $pool = $this->createNewPool($nonAvailablePool); 252 $questions = $this->getQuestionsForPool($nonAvailablePool); 253 254 $poolQidByTestQidMap = $this->copyQuestionsToPool($pool, $questions); 255 256 $this->updateTestQuestionStage($poolQidByTestQidMap); 257 258 $duplicatedTaxKeysMap = $this->duplicateTaxonomies($poolQidByTestQidMap, $pool); 259 260 $this->updateRelatedSourcePoolDefinitions($duplicatedTaxKeysMap, $pool->getId(), $nonAvailablePool->getId()); 261 262 return $pool; 263 } 264} 265