ILIAS  trunk Revision v11.0_alpha-1713-gd8962da2f67
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilTestImporter.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
24 
33 {
38  public static $finallyProcessedTestsRegistry = [];
39 
40  private readonly TestLogger $logger;
41  private readonly ilDBInterface $db;
42 
43  public function __construct()
44  {
45  global $DIC;
46  $this->logger = TestDIC::dic()['logging.logger'];
47  $this->db = $DIC['ilDB'];
48 
50  }
51 
52  public function importXmlRepresentation(
53  string $a_entity,
54  string $a_id,
55  string $a_xml,
56  ilImportMapping $a_mapping
57  ): void {
58  $results_file_path = null;
59  if ($new_id = (int) $a_mapping->getMapping('components/ILIAS/Container', 'objs', $a_id)) {
60  // container content
61  $new_obj = ilObjectFactory::getInstanceByObjId((int) $new_id, false);
62  $new_obj->saveToDb();
63 
64  ilSession::set('path_to_container_import_file', $this->getImportDirectory());
65  [$importdir, $xmlfile, $qtifile] = $this->buildImportDirectoriesFromContainerImport(
66  $this->getImportDirectory()
67  );
68  $selected_questions = [];
69  } else {
70  // single object
71  $new_id = (int) $a_mapping->getMapping('components/ILIAS/Test', 'tst', 'new_id');
72  $new_obj = ilObjectFactory::getInstanceByObjId($new_id, false);
73 
74  $selected_questions = ilSession::get('tst_import_selected_questions') ?? [];
75  [$subdir, $importdir, $xmlfile, $qtifile] = $this->buildImportDirectoriesFromImportFile(
76  ilSession::get('path_to_import_file')
77  );
78  $results_file_path = $this->buildResultsFilePath($importdir, $subdir);
79  ilSession::clear('tst_import_selected_questions');
80  }
81 
82  $new_obj->loadFromDb();
83 
84  if (!file_exists($xmlfile)) {
85  $this->logger->error(__METHOD__ . ': Cannot find xml definition: ' . $xmlfile);
86  return;
87  }
88  if (!file_exists($qtifile)) {
89  $this->logger->error(__METHOD__ . ': Cannot find xml definition: ' . $qtifile);
90  return;
91  }
92 
93  // start parsing of QTI files
94  $qti_parser = new ilQTIParser(
95  $importdir,
96  $qtifile,
98  $new_obj->getId(),
99  $selected_questions,
100  $a_mapping->getAllMappings()
101  );
102  $qti_parser->setTestObject($new_obj);
103  $qti_parser->startParsing();
104  $new_obj = $qti_parser->getTestObject();
105 
106  // import page data
107  $question_page_parser = new ilQuestionPageParser(
108  $new_obj,
109  $xmlfile,
110  $importdir
111  );
112  $question_page_parser->setQuestionMapping($qti_parser->getImportMapping());
113  $question_page_parser->startParsing();
114 
115  $a_mapping = $this->addTaxonomyAndQuestionsMapping($qti_parser->getQuestionIdMapping(), $new_obj->getId(), $a_mapping);
116 
117  if ($new_obj->isRandomTest()) {
118  $this->importRandomQuestionSetConfig($new_obj, $xmlfile, $a_mapping);
119  }
120 
121  if ($results_file_path !== null && file_exists($results_file_path)) {
122  $results = new ilTestResultsImportParser($results_file_path, $new_obj, $this->db, $this->logger);
123  $results->setQuestionIdMapping($a_mapping->getMappingsOfEntity('components/ILIAS/Test', 'quest'));
124  $results->setSrcPoolDefIdMapping($a_mapping->getMappingsOfEntity('components/ILIAS/Test', 'rnd_src_pool_def'));
125  $results->startParsing();
126  }
127 
128  $new_obj->saveToDb(); // this creates test_fi
129  $new_obj->update(); // this saves ilObject data
130 
131  // import skill assignments
132  $importedAssignmentList = $this->importQuestionSkillAssignments($a_mapping, $new_obj, $xmlfile);
133  $this->importSkillLevelThresholds($a_mapping, $importedAssignmentList, $new_obj, $xmlfile);
134 
135  $a_mapping->addMapping("components/ILIAS/Test", "tst", (string) $a_id, (string) $new_obj->getId());
136  $a_mapping->addMapping(
137  "components/ILIAS/MetaData",
138  "md",
139  $a_id . ":0:tst",
140  $new_obj->getId() . ":0:tst"
141  );
142  }
143 
145  array $question_id_mapping,
146  int $new_obj_id,
147  ilImportMapping $mapping
148  ): ilImportMapping {
149  foreach ($question_id_mapping as $old_question_id => $new_question_id) {
150  $mapping->addMapping(
151  'components/ILIAS/Taxonomy',
152  'tax_item',
153  "tst:quest:{$old_question_id}",
154  (string) $new_question_id
155  );
156 
157  $mapping->addMapping(
158  'components/ILIAS/Taxonomy',
159  'tax_item_obj_id',
160  "tst:quest:{$old_question_id}",
161  (string) $new_obj_id
162  );
163 
164  $mapping->addMapping(
165  'components/ILIAS/Test',
166  'quest',
167  (string) $old_question_id,
168  (string) $new_question_id
169  );
170  }
171 
172  return $mapping;
173  }
174 
175  public function finalProcessing(ilImportMapping $a_mapping): void
176  {
177  $maps = $a_mapping->getMappingsOfEntity("components/ILIAS/Test", "tst");
178 
179  foreach ($maps as $old => $new) {
180  if ($old == "new_id" || (int) $old <= 0) {
181  continue;
182  }
183 
184  if (isset(self::$finallyProcessedTestsRegistry[$new])) {
185  continue;
186  }
187 
188  $test_obj = ilObjectFactory::getInstanceByObjId((int) $new, false);
189  if ($test_obj->isRandomTest()) {
190  $this->finalRandomTestTaxonomyProcessing($a_mapping, (string) $old, $new, $test_obj);
191  }
192 
193  self::$finallyProcessedTestsRegistry[$new] = true;
194  }
195  }
196 
198  ilImportMapping $mapping,
199  string $old_tst_obj_id,
200  string $new_tst_obj_id,
201  ilObjTest $test_obj
202  ): void {
203  $new_tax_ids = $mapping->getMapping(
204  'components/ILIAS/Taxonomy',
205  'tax_usage_of_obj',
206  $old_tst_obj_id
207  );
208 
209  if ($new_tax_ids !== null) {
210  foreach (explode(':', $new_tax_ids) as $tax_id) {
211  ilObjTaxonomy::saveUsage((int) $tax_id, (int) $new_tst_obj_id);
212  }
213  }
214 
215  $src_pool_def_list = new ilTestRandomQuestionSetSourcePoolDefinitionList(
216  $this->db,
217  $test_obj,
219  $this->db,
220  $test_obj
221  )
222  );
223 
224  $src_pool_def_list->loadDefinitions();
225 
226  foreach ($src_pool_def_list as $definition) {
227  $mapped_taxonomy_filter = $definition->getMappedTaxonomyFilter();
228  if ($mapped_taxonomy_filter === []) {
229  continue;
230  }
231 
232  $definition->setMappedTaxonomyFilter(
234  $mapping,
235  $mapped_taxonomy_filter
236  )
237  );
238  $definition->saveToDb();
239  }
240  }
241 
242  protected function getNewMappedTaxonomyFilter(
243  ilImportMapping $mapping,
244  array $mapped_filter
245  ): array {
246  $new_mapped_filter = [];
247  foreach ($mapped_filter as $tax_id => $tax_nodes) {
248  $new_tax_id = $mapping->getMapping(
249  'components/ILIAS/Taxonomy',
250  'tax',
251  (string) $tax_id
252  );
253 
254  if ($new_tax_id === null) {
255  continue;
256  }
257 
258  $new_mapped_filter[$new_tax_id] = [];
259 
260  foreach ($tax_nodes as $tax_node_id) {
261  $new_tax_node_id = $mapping->getMapping(
262  'components/ILIAS/Taxonomy',
263  'tax_tree',
264  (string) $tax_node_id
265  );
266 
267  if ($new_tax_node_id === null) {
268  continue;
269  }
270 
271  $new_mapped_filter[$new_tax_id][] = $new_tax_node_id;
272  }
273  }
274 
275  return $new_mapped_filter;
276  }
277 
279  ilObjTest $test_obj,
280  ?string $xml_file,
281  \ilImportMapping $a_mapping
282  ): void {
283  $test_obj->questions = [];
284  $parser = new ilObjTestXMLParser($xml_file);
285  $parser->setTestOBJ($test_obj);
286  $parser->setImportMapping($a_mapping);
287  $parser->startParsing();
288  }
289 
290  protected function importQuestionSkillAssignments(
291  ilImportMapping $mapping,
292  ilObjTest $test_obj,
293  ?string $xml_file
295  $parser = new ilAssQuestionSkillAssignmentXmlParser($xml_file);
296  $parser->startParsing();
297 
298  $importer = new ilAssQuestionSkillAssignmentImporter();
299  $importer->setTargetParentObjId($test_obj->getId());
300  $importer->setImportInstallationId((int) $this->getInstallId());
301  $importer->setImportMappingRegistry($mapping);
302  $importer->setImportMappingComponent('components/ILIAS/Test');
303  $importer->setImportAssignmentList($parser->getAssignmentList());
304 
305  $importer->import();
306 
307  if ($importer->getFailedImportAssignmentList()->assignmentsExist()) {
308  $qsaImportFails = new ilAssQuestionSkillAssignmentImportFails($test_obj->getId());
309  $qsaImportFails->registerFailedImports($importer->getFailedImportAssignmentList());
310 
311  $test_obj->getObjectProperties()->storePropertyIsOnline(
312  $test_obj->getObjectProperties()->getPropertyIsOnline()->withOffline()
313  );
314  }
315 
316  return $importer->getSuccessImportAssignmentList();
317  }
318 
319  protected function importSkillLevelThresholds(
320  ilImportMapping $mapping,
321  ilAssQuestionSkillAssignmentList $assignment_list,
322  ilObjTest $test_obj,
323  ?string $xml_file
324  ): void {
325  $parser = new ilTestSkillLevelThresholdXmlParser($xml_file);
326  $parser->initSkillLevelThresholdImportList();
327  $parser->startParsing();
328 
329  $importer = new ilTestSkillLevelThresholdImporter($this->db);
330  $importer->setTargetTestId($test_obj->getTestId());
331  $importer->setImportInstallationId((int) $this->getInstallId());
332  $importer->setImportMappingRegistry($mapping);
333  $importer->setImportedQuestionSkillAssignmentList($assignment_list);
334  $importer->setImportThresholdList($parser->getSkillLevelThresholdImportList());
335  $importer->import();
336 
337  if ($importer->getFailedThresholdImportSkillList()->skillsExist()) {
338  $sltImportFails = new ilTestSkillLevelThresholdImportFails($test_obj->getId());
339  $sltImportFails->registerFailedImports($importer->getFailedThresholdImportSkillList());
340 
341  $test_obj->setOfflineStatus(true);
342  }
343  }
344 }
static get(string $a_var)
importXmlRepresentation(string $a_entity, string $a_id, string $a_xml, ilImportMapping $a_mapping)
getNewMappedTaxonomyFilter(ilImportMapping $mapping, array $mapped_filter)
registerFailedImports(ilAssQuestionAssignedSkillList $skillList)
getTestId()
Gets the database id of the additional test data.
importRandomQuestionSetConfig(ilObjTest $test_obj, ?string $xml_file, \ilImportMapping $a_mapping)
addMapping(string $a_comp, string $a_entity, string $a_old_id, string $a_new_id)
buildImportDirectoriesFromContainerImport(string $importdir)
buildResultsFilePath(string $importdir, string $subdir)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
finalRandomTestTaxonomyProcessing(ilImportMapping $mapping, string $old_tst_obj_id, string $new_tst_obj_id, ilObjTest $test_obj)
Importer class for files.
getMapping(string $a_comp, string $a_entity, string $a_old_id)
getMappingsOfEntity(string $a_comp, string $a_entity)
importQuestionSkillAssignments(ilImportMapping $mapping, ilObjTest $test_obj, ?string $xml_file)
readonly TestLogger $logger
global $DIC
Definition: shib_login.php:22
Legacy Content Object Parser.
readonly ilDBInterface $db
$results
setOfflineStatus(bool $status)
addTaxonomyAndQuestionsMapping(array $question_id_mapping, int $new_obj_id, ilImportMapping $mapping)
setTestObject(ilObjTest $tst_object)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static saveUsage(int $a_tax_id, int $a_obj_id)
static getInstanceByObjId(?int $obj_id, bool $stop_on_error=true)
get an instance of an Ilias object by object id
importSkillLevelThresholds(ilImportMapping $mapping, ilAssQuestionSkillAssignmentList $assignment_list, ilObjTest $test_obj, ?string $xml_file)
__construct(Container $dic, ilPlugin $plugin)
finalProcessing(ilImportMapping $a_mapping)
array buildImportDirectoriesFromImportFile(string $file_to_import)
static $finallyProcessedTestsRegistry
static clear(string $a_var)
registerFailedImports(ilAssQuestionSkillAssignmentImportList $assignmentList)
static set(string $a_var, $a_val)
Set a value.
Xml importer class.