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