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