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