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