ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilTestRandomQuestionSetConfig.php
Go to the documentation of this file.
1 <?php
2 
28 {
29  public const QUESTION_AMOUNT_CONFIG_MODE_PER_TEST = 'TEST';
30  public const QUESTION_AMOUNT_CONFIG_MODE_PER_POOL = 'POOL';
31 
36 
41 
45  private $questionAmountPerTest = null;
46 
51 
52  //fau: fixRandomTestBuildable - variable for messages
53  private $buildableMessages = array();
54  // fau.
55 
60  {
61  $this->requirePoolsWithHomogeneousScoredQuestions = $requirePoolsWithHomogeneousScoredQuestions;
62  }
63 
68  {
70  }
71 
76  {
77  $this->questionAmountConfigurationMode = $questionAmountConfigurationMode;
78  }
79 
83  public function getQuestionAmountConfigurationMode(): ?string
84  {
86  }
87 
92  {
93  return $this->getQuestionAmountConfigurationMode() == self::QUESTION_AMOUNT_CONFIG_MODE_PER_POOL;
94  }
95 
100  {
101  return $this->getQuestionAmountConfigurationMode() == self::QUESTION_AMOUNT_CONFIG_MODE_PER_TEST;
102  }
103 
104  public function isValidQuestionAmountConfigurationMode($amountMode): bool
105  {
106  switch ($amountMode) {
107  case self::QUESTION_AMOUNT_CONFIG_MODE_PER_POOL:
108  case self::QUESTION_AMOUNT_CONFIG_MODE_PER_TEST:
109 
110  return true;
111  }
112 
113  return false;
114  }
115 
120  {
121  $this->questionAmountPerTest = $questionAmountPerTest;
122  }
123 
127  public function getQuestionAmountPerTest(): ?int
128  {
130  }
131 
136  {
137  $this->lastQuestionSyncTimestamp = $lastQuestionSyncTimestamp;
138  }
139 
143  public function getLastQuestionSyncTimestamp(): ?int
144  {
146  }
147 
148  //fau: fixRandomTestBuildable - function to get messages
149  public function getBuildableMessages(): array
150  {
152  }
153  // fau.
154 
155  // -----------------------------------------------------------------------------------------------------------------
156 
163  public function initFromArray($dataArray)
164  {
165  foreach ($dataArray as $field => $value) {
166  switch ($field) {
167  case 'req_pools_homo_scored': $this->setPoolsWithHomogeneousScoredQuestionsRequired($value);
168  break;
169  case 'quest_amount_cfg_mode': $this->setQuestionAmountConfigurationMode($value);
170  break;
171  case 'quest_amount_per_test': $this->setQuestionAmountPerTest($value);
172  break;
173  case 'quest_sync_timestamp': $this->setLastQuestionSyncTimestamp($value);
174  break;
175  }
176  }
177  }
178 
184  public function loadFromDb(): bool
185  {
186  $res = $this->db->queryF(
187  "SELECT * FROM tst_rnd_quest_set_cfg WHERE test_fi = %s",
188  array('integer'),
189  array($this->testOBJ->getTestId())
190  );
191 
192  while ($row = $this->db->fetchAssoc($res)) {
193  $this->initFromArray($row);
194 
195  return true;
196  }
197 
198  return false;
199  }
200 
204  public function saveToDb()
205  {
206  if ($this->dbRecordExists($this->testOBJ->getTestId())) {
207  $this->updateDbRecord($this->testOBJ->getTestId());
208  } else {
209  $this->insertDbRecord($this->testOBJ->getTestId());
210  }
211  }
212 
218  public function cloneToDbForTestId($testId)
219  {
220  $this->insertDbRecord($testId);
221  }
222 
226  public function deleteFromDb()
227  {
228  $this->db->manipulateF(
229  "DELETE FROM tst_rnd_quest_set_cfg WHERE test_fi = %s",
230  array('integer'),
231  array($this->testOBJ->getTestId())
232  );
233  }
234 
235  // -----------------------------------------------------------------------------------------------------------------
236 
243  private function dbRecordExists($testId): bool
244  {
245  $res = $this->db->queryF(
246  "SELECT COUNT(*) cnt FROM tst_rnd_quest_set_cfg WHERE test_fi = %s",
247  array('integer'),
248  array($testId)
249  );
250 
251  $row = $this->db->fetchAssoc($res);
252 
253  return (bool) $row['cnt'];
254  }
255 
262  private function updateDbRecord($testId)
263  {
264  $this->db->update(
265  'tst_rnd_quest_set_cfg',
266  array(
267  'req_pools_homo_scored' => array('integer', (int) $this->arePoolsWithHomogeneousScoredQuestionsRequired()),
268  'quest_amount_cfg_mode' => array('text', $this->getQuestionAmountConfigurationMode()),
269  'quest_amount_per_test' => array('integer', (int) $this->getQuestionAmountPerTest()),
270  'quest_sync_timestamp' => array('integer', (int) $this->getLastQuestionSyncTimestamp())
271  ),
272  array(
273  'test_fi' => array('integer', $testId)
274  )
275  );
276  }
277 
284  private function insertDbRecord($testId)
285  {
286  $this->db->insert('tst_rnd_quest_set_cfg', array(
287  'test_fi' => array('integer', $testId),
288  'req_pools_homo_scored' => array('integer', (int) $this->arePoolsWithHomogeneousScoredQuestionsRequired()),
289  'quest_amount_cfg_mode' => array('text', $this->getQuestionAmountConfigurationMode()),
290  'quest_amount_per_test' => array('integer', (int) $this->getQuestionAmountPerTest()),
291  'quest_sync_timestamp' => array('integer', (int) $this->getLastQuestionSyncTimestamp())
292  ));
293  }
294 
295  // -----------------------------------------------------------------------------------------------------------------
296 
297  public function isQuestionSetConfigured(): bool
298  {
299  return (
300  $this->getLastQuestionSyncTimestamp() != 0
302  && $this->hasSourcePoolDefinitions()
303  && $this->isQuestionSetBuildable()
304  );
305  }
306 
307  public function isQuestionAmountConfigComplete(): bool
308  {
310  $sourcePoolDefinitionList = $this->buildSourcePoolDefinitionList($this->testOBJ);
311 
312  $sourcePoolDefinitionList->loadDefinitions();
313 
314  foreach ($sourcePoolDefinitionList as $definition) {
315  if ($definition->getQuestionAmount() < 1) {
316  return false;
317  }
318  }
319  } elseif ($this->getQuestionAmountPerTest() < 1) {
320  return false;
321  }
322 
323  return true;
324  }
325 
326  public function hasSourcePoolDefinitions(): bool
327  {
328  $sourcePoolDefinitionList = $this->buildSourcePoolDefinitionList($this->testOBJ);
329 
330  return $sourcePoolDefinitionList->savedDefinitionsExist();
331  }
332 
333  public function isQuestionSetBuildable(): bool
334  {
335  $sourcePoolDefinitionList = $this->buildSourcePoolDefinitionList($this->testOBJ);
336  $sourcePoolDefinitionList->loadDefinitions();
337 
338  $stagingPoolQuestionList = new ilTestRandomQuestionSetStagingPoolQuestionList($this->db, $this->component_repository);
339 
340  $questionSetBuilder = ilTestRandomQuestionSetBuilder::getInstance($this->db, $this->testOBJ, $this, $sourcePoolDefinitionList, $stagingPoolQuestionList);
341 
342  //fau: fixRandomTestBuildable - get messages if set is not buildable
343  $buildable = $questionSetBuilder->checkBuildable();
344  $this->buildableMessages = $questionSetBuilder->getCheckMessages();
345  return $buildable;
346  // fau.
347 
348  return $questionSetBuilder->checkBuildable();
349  }
350 
351  public function doesQuestionSetRelatedDataExist(): bool
352  {
353  if ($this->dbRecordExists($this->testOBJ->getTestId())) {
354  return true;
355  }
356 
357  $sourcePoolDefinitionList = $this->buildSourcePoolDefinitionList($this->testOBJ);
358 
359  if ($sourcePoolDefinitionList->savedDefinitionsExist()) {
360  return true;
361  }
362 
363  return false;
364  }
365 
366  public function removeQuestionSetRelatedData(): void
367  {
368  $sourcePoolDefinitionList = $this->buildSourcePoolDefinitionList($this->testOBJ);
369  $sourcePoolDefinitionList->deleteDefinitions();
370 
371  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetStagingPoolBuilder.php';
373  $this->db,
374  $this->testOBJ
375  );
376  $stagingPool->reset();
377 
378  $this->deleteFromDb();
379  }
380 
382  {
383  $this->testOBJ->getScoreSettingsRepository()->store(
384  $this->testOBJ->getScoreSettings()->withResultDetailsSettings(
385  $this->testOBJ->getScoreSettings()->getResultDetailsSettings()->withTaxonomyFilterIds(array())
386  )
387  );
388  $this->testOBJ->saveToDb(true);
389  }
390 
396  public function cloneQuestionSetRelatedData(ilObjTest $cloneTestOBJ)
397  {
398  // clone general config
399 
400  $this->loadFromDb();
401  $this->cloneToDbForTestId($cloneTestOBJ->getTestId());
402 
403  // clone source pool definitions (selection rules)
404 
405  $sourcePoolDefinitionList = $this->buildSourcePoolDefinitionList($this->testOBJ);
406  $sourcePoolDefinitionList->loadDefinitions();
407  $definitionIdMap = $sourcePoolDefinitionList->cloneDefinitionsForTestId($cloneTestOBJ->getTestId());
408  $this->registerClonedSourcePoolDefinitionIdMapping($cloneTestOBJ, $definitionIdMap);
409 
410  // build new question stage for cloned test
411 
412  $sourcePoolDefinitionList = $this->buildSourcePoolDefinitionList($cloneTestOBJ);
413  $stagingPool = $this->buildStagingPoolBuilder($cloneTestOBJ);
414 
415  $sourcePoolDefinitionList->loadDefinitions();
416  $stagingPool->rebuild($sourcePoolDefinitionList);
417  $sourcePoolDefinitionList->saveDefinitions();
418 
419  $this->updateLastQuestionSyncTimestampForTestId($cloneTestOBJ->getTestId(), time());
420  }
421 
422  private function registerClonedSourcePoolDefinitionIdMapping(ilObjTest $cloneTestOBJ, $definitionIdMap)
423  {
424  global $DIC;
425  $ilLog = $DIC['ilLog'];
426 
427  require_once 'Services/CopyWizard/classes/class.ilCopyWizardOptions.php';
429 
430  foreach ($definitionIdMap as $originalDefinitionId => $cloneDefinitionId) {
431  $originalKey = $this->testOBJ->getRefId() . '_rndSelDef_' . $originalDefinitionId;
432  $mappedKey = $cloneTestOBJ->getRefId() . '_rndSelDef_' . $cloneDefinitionId;
433  $cwo->appendMapping($originalKey, $mappedKey);
434  $ilLog->write(__METHOD__ . ": Added random selection definition id mapping $originalKey <-> $mappedKey");
435  }
436  }
437 
439  {
441  $this->db,
442  $testOBJ,
444  $this->db,
445  $testOBJ
446  )
447  );
448  }
449 
451  {
452  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetStagingPoolBuilder.php';
453  $stagingPool = new ilTestRandomQuestionSetStagingPoolBuilder($this->db, $testOBJ);
454 
455  return $stagingPool;
456  }
457 
458  // -----------------------------------------------------------------------------------------------------------------
459 
461  {
462  $this->db->update(
463  'tst_rnd_quest_set_cfg',
464  array(
465  'quest_sync_timestamp' => array('integer', (int) $timestamp)
466  ),
467  array(
468  'test_fi' => array('integer', $testId)
469  )
470  );
471  }
472 
473  public function isResultTaxonomyFilterSupported(): bool
474  {
475  return true;
476  }
477 
478  // -----------------------------------------------------------------------------------------------------------------
479 
480  public function getSelectableQuestionPools(): array
481  {
482  return $this->testOBJ->getAvailableQuestionpools(
483  true,
485  false,
486  true,
487  true
488  );
489  }
490 
491  public function doesSelectableQuestionPoolsExist(): bool
492  {
493  return (bool) count($this->getSelectableQuestionPools());
494  }
495 
496  // -----------------------------------------------------------------------------------------------------------------
497 
498  public function areDepenciesBroken(): bool
499  {
500  return $this->testOBJ->isTestFinalBroken();
501  }
502 
503  public function getDepenciesBrokenMessage(ilLanguage $lng): string
504  {
505  return $lng->txt('tst_old_style_rnd_quest_set_broken');
506  }
507 
508  public function isValidRequestOnBrokenQuestionSetDepencies($nextClass, $cmd): bool
509  {
510  //vd($nextClass, $cmd);
511 
512  switch ($nextClass) {
513  case 'ilobjectmetadatagui':
514  case 'ilpermissiongui':
515 
516  return true;
517 
518  case 'ilobjtestgui':
519  case '':
520 
521  $cmds = array(
522  'infoScreen', 'participants', 'npSetFilter', 'npResetFilter',
523  //'deleteAllUserResults', 'confirmDeleteAllUserResults',
524  //'deleteSingleUserResults', 'confirmDeleteSelectedUserData', 'cancelDeleteSelectedUserData'
525  );
526 
527  if (in_array($cmd, $cmds)) {
528  return true;
529  }
530 
531  break;
532  }
533 
534  return false;
535  }
536 
537  public function getHiddenTabsOnBrokenDepencies(): array
538  {
539  return array(
540  'assQuestions', 'settings', 'manscoring', 'scoringadjust', 'statistics', 'history', 'export'
541  );
542  }
543 
544  // -----------------------------------------------------------------------------------------------------------------
545 
547  {
548  $definitionList = $this->buildSourcePoolDefinitionList($this->testOBJ);
549  $definitionList->loadDefinitions();
550 
551  $poolTitles = array();
552 
553  foreach ($definitionList as $definition) {
554  /* @var ilTestRandomQuestionSetSourcePoolDefinition $definition */
555 
556  $refId = current(ilObject::_getAllReferences($definition->getPoolId()));
557  $href = ilLink::_getLink($refId, 'qpl');
558  $title = $definition->getPoolTitle();
559 
560  $poolTitles[$definition->getPoolId()] = "<a href=\"$href\" alt=\"$title\">$title</a>";
561  }
562 
563  return implode(', ', $poolTitles);
564  }
565 }
insertDbRecord($testId)
inserts a new record for the question set config for the current test into the database ...
cloneQuestionSetRelatedData(ilObjTest $cloneTestOBJ)
removes all question set config related data for cloned/copied test
$res
Definition: ltiservices.php:69
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
$lng
setQuestionAmountConfigurationMode($questionAmountConfigurationMode)
static _getAllReferences(int $id)
get all reference ids for object ID
getTestId()
Gets the database id of the additional test data.
registerClonedSourcePoolDefinitionIdMapping(ilObjTest $cloneTestOBJ, $definitionIdMap)
$refId
Definition: xapitoken.php:58
loadFromDb()
loads the question set config for current test from the database
global $DIC
Definition: feed.php:28
initFromArray($dataArray)
initialises the current object instance with values from matching properties within the passed array ...
cloneToDbForTestId($testId)
saves the question set config for test with given id to the database
setLastQuestionSyncTimestamp($lastQuestionSyncTimestamp)
setPoolsWithHomogeneousScoredQuestionsRequired($requirePoolsWithHomogeneousScoredQuestions)
static getInstance(ilDBInterface $db, ilObjTest $testOBJ, ilTestRandomQuestionSetConfig $questionSetConfig, ilTestRandomQuestionSetSourcePoolDefinitionList $sourcePoolDefinitionList, ilTestRandomQuestionSetStagingPoolQuestionList $stagingPoolQuestionList)
saveToDb()
saves the question set config for current test to the database
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:70
deleteFromDb()
deletes the question set config for current test from the database
updateDbRecord($testId)
updates the record in the database that corresponds to the question set config for the current test ...
static _getInstance(int $a_copy_id)
dbRecordExists($testId)
checks wether a question set config for current test exists in the database