ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilTestImporter.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 include_once("./Services/Export/classes/class.ilXmlImporter.php");
5 
14 {
18  public static $finallyProcessedTestsRegistry = array();
19 
26  public function importXmlRepresentation($a_entity, $a_id, $a_xml, $a_mapping)
27  {
28  // Container import => test object already created
29  include_once "./Modules/Test/classes/class.ilObjTest.php";
31 
32  if ($new_id = $a_mapping->getMapping('Services/Container', 'objs', $a_id)) {
33  // container content
34  $newObj = ilObjectFactory::getInstanceByObjId($new_id, false);
35  $_SESSION['tst_import_subdir'] = $this->getImportPackageName();
36  $newObj->saveToDb(); // this generates test id first time
37  $questionParentObjId = $newObj->getId();
38  $newObj->setOfflineStatus(false);
39  $questionParentObjId = $newObj->getId();
40  } else {
41  // single object
42  $new_id = $a_mapping->getMapping('Modules/Test', 'tst', 'new_id');
43  $newObj = ilObjectFactory::getInstanceByObjId($new_id, false);
44 
45  if (isset($_SESSION['tst_import_qst_parent'])) {
46  $questionParentObjId = $_SESSION['tst_import_qst_parent'];
47  } else {
48  $questionParentObjId = $newObj->getId();
49  }
50  }
51 
52  $newObj->loadFromDb();
53 
54  list($xml_file, $qti_file) = $this->parseXmlFileNames();
55 
56  global $DIC; /* @var ILIAS\DI\Container $DIC */
57  if (!@file_exists($xml_file)) {
58  $DIC['ilLog']->write(__METHOD__ . ': Cannot find xml definition: ' . $xml_file);
59  return false;
60  }
61  if (!@file_exists($qti_file)) {
62  $DIC['ilLog']->write(__METHOD__ . ': Cannot find xml definition: ' . $qti_file);
63  return false;
64  }
65 
66  /* @var ilObjTest $newObj */
67 
68  // FIXME: Copied from ilObjTestGUI::importVerifiedFileObject
69  // TODO: move all logic to ilObjTest::importVerifiedFile and call
70  // this method from ilObjTestGUI and ilTestImporter
71  $newObj->mark_schema->flush();
72 
73 
74  if (isset($_SESSION['tst_import_idents'])) {
75  $idents = $_SESSION['tst_import_idents'];
76  } else {
77  $idents = null;
78  }
79 
80  // start parsing of QTI files
81  include_once "./Services/QTI/classes/class.ilQTIParser.php";
82  $qtiParser = new ilQTIParser($qti_file, IL_MO_PARSE_QTI, $questionParentObjId, $idents);
83  $qtiParser->setTestObject($newObj);
84  $result = $qtiParser->startParsing();
85 
86  // import page data
87  include_once("./Modules/LearningModule/classes/class.ilContObjParser.php");
88  $contParser = new ilContObjParser($newObj, $xml_file, basename($this->getImportDirectory()));
89  $contParser->setQuestionMapping($qtiParser->getImportMapping());
90  $contParser->startParsing();
91 
92  foreach ($qtiParser->getQuestionIdMapping() as $oldQuestionId => $newQuestionId) {
93  $a_mapping->addMapping(
94  "Services/Taxonomy",
95  "tax_item",
96  "tst:quest:$oldQuestionId",
97  $newQuestionId
98  );
99 
100  $a_mapping->addMapping(
101  "Services/Taxonomy",
102  "tax_item_obj_id",
103  "tst:quest:$oldQuestionId",
104  $newObj->getId()
105  );
106 
107  $a_mapping->addMapping(
108  "Modules/Test",
109  "quest",
110  $oldQuestionId,
111  $newQuestionId
112  );
113  }
114 
115  if ($newObj->isRandomTest()) {
116  $newObj->questions = array();
117  $this->importRandomQuestionSetConfig($newObj, $xml_file, $a_mapping);
118  }
119 
120  // import test results
121  if (@file_exists($_SESSION["tst_import_results_file"])) {
122  include_once("./Modules/Test/classes/class.ilTestResultsImportParser.php");
123  $results = new ilTestResultsImportParser($_SESSION["tst_import_results_file"], $newObj);
124  $results->setQuestionIdMapping($a_mapping->getMappingsOfEntity('Modules/Test', 'quest'));
125  $results->setSrcPoolDefIdMapping($a_mapping->getMappingsOfEntity('Modules/Test', 'rnd_src_pool_def'));
126  $results->startParsing();
127  }
128 
129  $newObj->saveToDb(); // this creates test_fi
130  $newObj->update(); // this saves ilObject data
131 
132  // import skill assignments
133  $importedAssignmentList = $this->importQuestionSkillAssignments($a_mapping, $newObj, $xml_file);
134  $this->importSkillLevelThresholds($a_mapping, $importedAssignmentList, $newObj, $xml_file);
135 
136  $a_mapping->addMapping("Modules/Test", "tst", $a_id, $newObj->getId());
137 
139  }
140 
147  public function finalProcessing($a_mapping)
148  {
149  $maps = $a_mapping->getMappingsOfEntity("Modules/Test", "tst");
150 
151  foreach ($maps as $old => $new) {
152  if ($old == "new_id" || (int) $old <= 0) {
153  continue;
154  }
155 
156  if (isset(self::$finallyProcessedTestsRegistry[$new])) {
157  continue;
158  }
159 
160  /* @var ilObjTest $testOBJ */
161  $testOBJ = ilObjectFactory::getInstanceByObjId($new, false);
162  if ($testOBJ->isRandomTest()) {
163  $this->finalRandomTestTaxonomyProcessing($a_mapping, $old, $new, $testOBJ);
164  }
165 
166  self::$finallyProcessedTestsRegistry[$new] = true;
167  }
168  }
169 
170  protected function finalRandomTestTaxonomyProcessing(ilImportMapping $mapping, $oldTstObjId, $newTstObjId, ilObjTest $testOBJ)
171  {
172  require_once 'Services/Taxonomy/classes/class.ilObjTaxonomy.php';
173 
174  // get all new taxonomies of this object and store usage for test object
175 
176  $new_tax_ids = $mapping->getMapping(
177  'Services/Taxonomy',
178  'tax_usage_of_obj',
179  $oldTstObjId
180  );
181 
182  if ($new_tax_ids !== false) {
183  $tax_ids = explode(":", $new_tax_ids);
184 
185  foreach ($tax_ids as $tid) {
186  ilObjTaxonomy::saveUsage($tid, $newTstObjId);
187  }
188  }
189 
190  // update all source pool definition's tax/taxNode ids with new mapped id
191  global $DIC; /* @var ILIAS\DI\Container $DIC */
192  $ilDB = $DIC['ilDB'];
193 
194  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionFactory.php';
196  $ilDB,
197  $testOBJ
198  );
199 
200  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionList.php';
202  $ilDB,
203  $testOBJ,
204  $srcPoolDefFactory
205  );
206 
207  $srcPoolDefList->loadDefinitions();
208 
209  foreach ($srcPoolDefList as $definition) {
210  // #21330
211  if (!is_array($definition->getMappedTaxonomyFilter()) || 0 === count($definition->getMappedTaxonomyFilter())) {
212  continue;
213  }
214 
215  $definition->setMappedTaxonomyFilter(
217  $mapping,
218  $definition->getMappedTaxonomyFilter()
219  )
220  );
221  $definition->saveToDb();
222  }
223  }
224 
230  protected function getNewMappedTaxonomyFilter(ilImportMapping $mapping, array $mappedFilter)
231  {
232  $newMappedFilter = array();
233 
234  foreach ($mappedFilter as $taxId => $taxNodes) {
235  $newTaxId = $mapping->getMapping(
236  'Services/Taxonomy',
237  'tax',
238  $taxId
239  );
240 
241  if (!$newTaxId) {
242  continue;
243  }
244 
245  $newMappedFilter[$newTaxId] = array();
246 
247  foreach ($taxNodes as $taxNodeId) {
248  $newTaxNodeId = $mapping->getMapping(
249  'Services/Taxonomy',
250  'tax_tree',
251  $taxNodeId
252  );
253 
254  if (!$newTaxNodeId) {
255  continue;
256  }
257 
258  $newMappedFilter[$newTaxId][] = $newTaxNodeId;
259  }
260  }
261 
262  return $newMappedFilter;
263  }
264 
269  protected function parseXmlFileNames()
270  {
271  global $DIC; /* @var ILIAS\DI\Container $DIC */
272  $DIC['ilLog']->write(__METHOD__ . ': ' . $this->getImportDirectory());
273 
274  $basename = basename($this->getImportDirectory());
275 
276  $xml = $this->getImportDirectory() . '/' . $basename . '.xml';
277  $qti = $this->getImportDirectory() . '/' . preg_replace('/test|tst/', 'qti', $basename) . '.xml';
278 
279  return array($xml,$qti);
280  }
281 
282  private function getImportDirectoryContainer()
283  {
284  $dir = $this->getImportDirectory();
285  $dir = dirname($dir);
286  return $dir;
287  }
288 
289  private function getImportPackageName()
290  {
291  $dir = $this->getImportDirectory();
292  $name = basename($dir);
293  return $name;
294  }
295 
296  protected function importRandomQuestionSetConfig(ilObjTest $testOBJ, $xmlFile, $a_mapping)
297  {
298  require_once 'Modules/Test/classes/class.ilObjTestXMLParser.php';
299  $parser = new ilObjTestXMLParser($xmlFile);
300  $parser->setTestOBJ($testOBJ);
301  $parser->setImportMapping($a_mapping);
302  $parser->startParsing();
303  }
304 
311  protected function importQuestionSkillAssignments(ilImportMapping $mapping, ilObjTest $testOBJ, $xmlFile)
312  {
313  require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssQuestionSkillAssignmentXmlParser.php';
315  $parser->startParsing();
316 
317  require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssQuestionSkillAssignmentImporter.php';
318  $importer = new ilAssQuestionSkillAssignmentImporter();
319  $importer->setTargetParentObjId($testOBJ->getId());
320  $importer->setImportInstallationId($this->getInstallId());
321  $importer->setImportMappingRegistry($mapping);
322  $importer->setImportMappingComponent('Modules/Test');
323  $importer->setImportAssignmentList($parser->getAssignmentList());
324 
325  $importer->import();
326 
327  if ($importer->getFailedImportAssignmentList()->assignmentsExist()) {
328  require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssQuestionSkillAssignmentImportFails.php';
329  $qsaImportFails = new ilAssQuestionSkillAssignmentImportFails($testOBJ->getId());
330  $qsaImportFails->registerFailedImports($importer->getFailedImportAssignmentList());
331 
332  $testOBJ->setOnline(false);
333  }
334 
335  return $importer->getSuccessImportAssignmentList();
336  }
337 
344  protected function importSkillLevelThresholds(ilImportMapping $mapping, ilAssQuestionSkillAssignmentList $assignmentList, ilObjTest $testOBJ, $xmlFile)
345  {
346  require_once 'Modules/Test/classes/class.ilTestSkillLevelThresholdXmlParser.php';
348  $parser->startParsing();
349 
350  require_once 'Modules/Test/classes/class.ilTestSkillLevelThresholdImporter.php';
351  $importer = new ilTestSkillLevelThresholdImporter();
352  $importer->setTargetTestId($testOBJ->getTestId());
353  $importer->setImportInstallationId($this->getInstallId());
354  $importer->setImportMappingRegistry($mapping);
355  $importer->setImportedQuestionSkillAssignmentList($assignmentList);
356  $importer->setImportThresholdList($parser->getSkillLevelThresholdImportList());
357  $importer->import();
358 
359  if ($importer->getFailedThresholdImportSkillList()->skillsExist()) {
360  require_once 'Modules/Test/classes/class.ilTestSkillLevelThresholdImportFails.php';
361  $sltImportFails = new ilTestSkillLevelThresholdImportFails($testOBJ->getId());
362  $sltImportFails->registerFailedImports($importer->getFailedThresholdImportSkillList());
363 
364  $testOBJ->setOfflineStatus(true);
365  }
366  }
367 }
getMapping($a_comp, $a_entity, $a_old_id)
Get a mapping.
Content Object Parser.
setOnline($a_online=true)
$_SESSION["AccountId"]
$result
global $DIC
Definition: saml.php:7
registerFailedImports(ilAssQuestionAssignedSkillList $skillList)
getImportDirectory()
Get import directory.
getTestId()
Gets the database id of the additional test data.
getNewMappedTaxonomyFilter(ilImportMapping $mapping, array $mappedFilter)
parseXmlFileNames()
Create qti and xml file name.
importQuestionSkillAssignments(ilImportMapping $mapping, ilObjTest $testOBJ, $xmlFile)
Importer class for files.
getId()
get object id public
const IL_MO_PARSE_QTI
finalRandomTestTaxonomyProcessing(ilImportMapping $mapping, $oldTstObjId, $newTstObjId, ilObjTest $testOBJ)
importXmlRepresentation($a_entity, $a_id, $a_xml, $a_mapping)
Import XML.
importRandomQuestionSetConfig(ilObjTest $testOBJ, $xmlFile, $a_mapping)
static getInstanceByObjId($a_obj_id, $stop_on_error=true)
get an instance of an Ilias object by object id
importSkillLevelThresholds(ilImportMapping $mapping, ilAssQuestionSkillAssignmentList $assignmentList, ilObjTest $testOBJ, $xmlFile)
finalProcessing($a_mapping)
Final processing.
$parser
Definition: BPMN2Parser.php:23
static saveUsage($a_tax_id, $a_obj_id)
Save Usage.
setOfflineStatus($a_status)
Set offline status.
$results
Definition: svg-scanner.php:47
global $ilDB
getInstallId()
Get installation id.
static $finallyProcessedTestsRegistry
registerFailedImports(ilAssQuestionSkillAssignmentImportList $assignmentList)
static _setImportDirectory($a_import_dir=null)
set import directory
Xml importer class.