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