ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilObjTestXMLParser.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
24
32{
34
35 private readonly ilDBInterface $db;
36 private readonly TestLogger $logger;
37 private readonly ilTree $tree;
39
40 protected ?ilObjTest $test_obj = null;
41
43
44 protected string $cdata = '';
45 protected ?array $attr = null;
46
47 private ?bool $in_random_question_set_config = null;
49 private ?bool $in_random_question_stage = null;
52
53 public function __construct(
54 ?string $path_to_file = '',
55 ?bool $throw_exception = false
56 ) {
57 global $DIC;
58 $this->db = $DIC['ilDB'];
59 $local_dic = TestDIC::dic();
60 $this->logger = $local_dic['logging.logger'];
61 $this->questionrepository = $local_dic['question.general_properties.repository'];
62 $this->tree = $DIC['tree'];
63 $this->component_repository = $DIC['component.repository'];
65 }
66
67 public function getTestOBJ(): ?\ilObjTest
68 {
69 return $this->test_obj;
70 }
71
72 public function setTestOBJ(\ilObjTest $test_obj): void
73 {
74 $this->test_obj = $test_obj;
75 }
76
77 public function getImportMapping(): ?\ilImportMapping
78 {
80 }
81
83 {
84 $this->import_mapping = $import_mapping;
85 }
86
87 public function setHandlers($xml_parser): void
88 {
89 xml_set_element_handler($xml_parser, $this->handlerBeginTag(...), $this->handlerEndTag(...));
90 xml_set_character_data_handler($xml_parser, $this->handlerCharacterData(...));
91 }
92
93 public function handlerBeginTag(
94 $xml_parser,
95 string $tag_name,
96 array $tag_attributes
97 ): void {
98 switch ($tag_name) {
99 case 'RandomQuestionSetConfig':
100 $this->in_random_question_set_config = true;
101 break;
102
103 case 'RandomQuestionSetSettings':
104 if ($this->in_random_question_set_config !== null) {
105 $this->in_random_question_set_settings = true;
106 $this->cdata = '';
107 $this->attr = $tag_attributes;
108 }
109 break;
110
111 case 'RandomQuestionStage':
112 if ($this->in_random_question_set_config !== null) {
113 $this->in_random_question_stage = true;
114 }
115 break;
116
117 case 'RandomQuestionStagingPool':
118 if ($this->in_random_question_stage !== null) {
119 $this->cdata = '';
120 $this->attr = $tag_attributes;
121 }
122 break;
123
124 case 'RandomQuestionSelectionDefinitions':
125 if ($this->in_random_question_set_config !== null) {
126 $this->in_random_question_selection_definitions = true;
127 }
128 break;
129
130 case 'RandomQuestionSelectionDefinition':
131 if ($this->in_random_question_selection_definitions !== null) {
132 $this->source_pool_definition = new ilTestRandomQuestionSetSourcePoolDefinition($this->db, $this->test_obj);
133 ;
134 $this->attr = $tag_attributes;
135 }
136 break;
137
138 case 'RandomQuestionSourcePoolTitle':
139 case 'RandomQuestionSourcePoolPath':
140 if ($this->source_pool_definition !== null) {
141 $this->cdata = '';
142 }
143 break;
144 }
145 }
146
147 public function handlerEndTag($xml_parser, string $tag_name): void
148 {
149 switch ($tag_name) {
150 case 'RandomQuestionSetConfig':
151 $this->in_random_question_set_config = false;
152 break;
153
154 case 'RandomQuestionSetSettings':
155 if ($this->in_random_question_set_config) {
156 $this->importRandomQuestionSetSettings($this->attr);
157 $this->attr = null;
158 }
159 break;
160
161 case 'RandomQuestionStage':
162 if ($this->in_random_question_set_config) {
163 $this->in_random_question_stage = false;
164 }
165 break;
166
167 case 'RandomQuestionStagingPool':
168 if ($this->in_random_question_set_config !== null
169 && $this->in_random_question_stage !== null) {
170 $this->importRandomQuestionStagingPool($this->attr, $this->cdata);
171 $this->attr = null;
172 $this->cdata = '';
173 }
174 break;
175
176 case 'RandomQuestionSelectionDefinitions':
177 if ($this->in_random_question_set_config) {
178 $this->in_random_question_selection_definitions = false;
179 }
180 break;
181
182 case 'RandomQuestionSelectionDefinition':
183 if ($this->in_random_question_set_config !== null
184 && $this->in_random_question_selection_definitions !== null) {
185 $this->importRandomQuestionSourcePoolDefinition($this->source_pool_definition, $this->attr);
186 $this->source_pool_definition->saveToDb();
187
188 $this->getImportMapping()->addMapping(
189 'components/ILIAS/Test',
190 'rnd_src_pool_def',
191 (string) $this->attr['id'],
192 (string) $this->source_pool_definition->getId()
193 );
194
195 $this->source_pool_definition = null;
196 $this->attr = null;
197 }
198 break;
199
200 case 'RandomQuestionSourcePoolTitle':
201 if ($this->source_pool_definition !== null) {
202 $this->source_pool_definition->setPoolTitle($this->cdata);
203 $this->cdata = '';
204 }
205 break;
206
207 case 'RandomQuestionSourcePoolPath':
208 if ($this->source_pool_definition !== null) {
209 $this->source_pool_definition->setPoolPath($this->cdata);
210 $this->cdata = '';
211 }
212 break;
213 }
214 }
215
216 public function handlerCharacterData($xml_parser, string $char_data): void
217 {
218 if ($char_data != "\n") {
219 // Replace multiple tabs with one space
220 $char_data = preg_replace("/\t+/", " ", $char_data);
221
222 $this->cdata .= $char_data;
223 }
224 }
225
226 protected function importRandomQuestionSetSettings($attr): void
227 {
228 $question_set_config = new ilTestRandomQuestionSetConfig(
229 $this->tree,
230 $this->db,
231 $this->lng,
232 $this->logger,
233 $this->component_repository,
234 $this->test_obj,
235 $this->questionrepository
236 );
237
238 if (!$question_set_config->isValidQuestionAmountConfigurationMode($attr['amountMode'])) {
239 throw new ilTestException(
240 'invalid random test question set config amount mode given: "' . $attr['amountMode'] . '"'
241 );
242 }
243
244 $question_set_config->setQuestionAmountConfigurationMode($attr['amountMode']);
245 $question_set_config->setQuestionAmountPerTest((int) $attr['questAmount']);
246 $question_set_config->setPoolsWithHomogeneousScoredQuestionsRequired((bool) $attr['homogeneous']);
247 $question_set_config->setLastQuestionSyncTimestamp((int) $attr['synctimestamp']);
248
249 $question_set_config->saveToDb();
250 }
251
252 protected function importRandomQuestionStagingPool(array $attr, string $cdata): void
253 {
254 $old_pool_id = $attr['poolId'];
255 $new_pool_id = $this->db->nextId('object_data'); // yes !!
256
257 $this->getImportMapping()->addMapping(
258 'components/ILIAS/Test',
259 'pool',
260 (string) $old_pool_id,
261 (string) $new_pool_id
262 );
263
264 $old_question_ids = explode(',', $cdata);
265
266 foreach ($old_question_ids as $old_question_id) {
267 $new_question_id = (int) $this->getImportMapping()->getMapping(
268 'components/ILIAS/Test',
269 'quest',
270 $old_question_id
271 );
272
273 $staging_question = new ilTestRandomQuestionSetStagingPoolQuestion($this->db);
274 $staging_question->setTestId($this->test_obj->getTestId());
275 $staging_question->setPoolId($new_pool_id);
276 $staging_question->setQuestionId($new_question_id);
277
278 $staging_question->saveQuestionStaging();
279 }
280 }
281
282 protected function importRandomQuestionSourcePoolDefinition(ilTestRandomQuestionSetSourcePoolDefinition $source_pool_definition, $attr): void
283 {
284 $source_pool_id = (int) $attr['poolId'];
285 $effective_pool_id = (int) $this->getImportMapping()->getMapping(
286 'components/ILIAS/Test',
287 'pool',
288 (string) $source_pool_id
289 );
290 $source_pool_definition->setPoolId($effective_pool_id);
291
292 $derive_from_obj_id = true;
293 // The ref_id might not be given in old export files, so we have to check for existence
294 if (isset($attr['ref_id']) && is_numeric($attr['ref_id'])) {
295 if ($source_pool_id === $effective_pool_id) {
296 $derive_from_obj_id = false;
297 $source_pool_definition->setPoolRefId((int) $attr['ref_id']);
298 }
299 }
300
301 if ($derive_from_obj_id) {
302 $ref_ids = ilObject::_getAllReferences($effective_pool_id);
303 $ref_id = current($ref_ids);
304 $source_pool_definition->setPoolRefId($ref_id ? $ref_id : null);
305 }
306
307 $source_pool_definition->setPoolQuestionCount((int) $attr['poolQuestCount']);
308 $source_pool_definition->setQuestionAmount((int) $attr['questAmount']);
309 $source_pool_definition->setSequencePosition((int) $attr['position']);
310
311 if (isset($attr['typeFilter']) && strlen($attr['typeFilter']) > 0) {
312 $source_pool_definition->setTypeFilterFromTypeTags(explode(',', $attr['typeFilter']));
313 }
314
315 // #21330
316 if (isset($attr['tax']) && isset($attr['taxNode'])) {
317 $mappedTaxFilter = [
318 (int) $attr['tax'] => [
319 (int) $attr['taxNode']
320 ]
321 ];
322 $source_pool_definition->setMappedTaxonomyFilter($mappedTaxFilter);
323 } elseif (isset($attr['taxFilter']) && strlen($attr['taxFilter']) > 0) {
324 $mappedTaxFilter = unserialize($attr['taxFilter'], ['allowed_classes' => false]);
325 $source_pool_definition->setMappedTaxonomyFilter($mappedTaxFilter);
326 }
327 }
328}
handlerCharacterData($xml_parser, string $char_data)
readonly TestLogger $logger
setImportMapping(\ilImportMapping $import_mapping)
importRandomQuestionSourcePoolDefinition(ilTestRandomQuestionSetSourcePoolDefinition $source_pool_definition, $attr)
handlerBeginTag( $xml_parser, string $tag_name, array $tag_attributes)
setTestOBJ(\ilObjTest $test_obj)
importRandomQuestionStagingPool(array $attr, string $cdata)
readonly GeneralQuestionPropertiesRepository $questionrepository
readonly ilDBInterface $db
handlerEndTag($xml_parser, string $tag_name)
ilTestRandomQuestionSetSourcePoolDefinition $source_pool_definition
readonly ilComponentRepository $component_repository
__construct(?string $path_to_file='', ?bool $throw_exception=false)
static _getAllReferences(int $id)
get all reference ids for object ID
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Base Exception for all Exceptions relating to Modules/Test.
setTypeFilterFromTypeTags(array $tags)
Set the type filter from a list of type tags.
setMappedTaxonomyFilter(array $filter=[])
set the original taxonomy filter condition
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
Readable part of repository interface to ilComponentDataDB.
Interface ilDBInterface.
$ref_id
Definition: ltiauth.php:66
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
global $DIC
Definition: shib_login.php:26