ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilCourseObjectiveQuestion.php
Go to the documentation of this file.
1 <?php
2 
24 {
25  public const TYPE_SELF_ASSESSMENT = 0;
26  public const TYPE_FINAL_TEST = 1;
27 
28  private int $objective_id = 0;
29  private array $questions = [];
30  private array $tests = [];
31  private int $tst_status = 0;
32  private int $tst_limit = 0;
33  private int $tst_ref_id = 0;
34  private int $tst_obj_id = 0;
35  private int $question_id = 0;
36 
37  protected ilLogger $logger;
38  protected ilDBInterface $db;
40  protected ilTree $tree;
41 
42  public function __construct(int $a_objective_id = 0)
43  {
44  global $DIC;
45 
46  $this->logger = $DIC->logger()->crs();
47  $this->objectDataCache = $DIC['ilObjDataCache'];
48  $this->db = $DIC->database();
49  $this->tree = $DIC->repositoryTree();
50 
51  $this->objective_id = $a_objective_id;
52  $this->__read();
53  }
54 
58  public static function lookupObjectivesOfQuestion(int $a_qid): array
59  {
60  global $DIC;
61 
62  $ilDB = $DIC->database();
63  $query = 'SELECT objective_id FROM crs_objective_qst ' .
64  'WHERE question_id = ' . $ilDB->quote($a_qid, 'integer');
65  $res = $ilDB->query($query);
66  $objectiveIds = array();
67  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
68  $objectiveIds[] = (int) $row->objective_id;
69  }
70  return $objectiveIds;
71  }
72 
73  public static function _isTestAssignedToObjective(int $a_test_id, int $a_objective_id): bool
74  {
75  global $DIC;
76 
77  $ilDB = $DIC->database();
78 
79  $query = "SELECT qst_ass_id FROM crs_objective_qst " .
80  "WHERE ref_id = " . $ilDB->quote($a_test_id, 'integer') . " " .
81  "AND objective_id = " . $ilDB->quote($a_objective_id, 'integer');
82  $res = $ilDB->query($query);
83  return (bool) $res->numRows();
84  }
85 
86  public function cloneDependencies(int $a_new_objective, int $a_copy_id): void
87  {
88  $cwo = ilCopyWizardOptions::_getInstance($a_copy_id);
89  $mappings = $cwo->getMappings();
90  foreach ($this->getQuestions() as $question) {
91  $mapping_key = $question['ref_id'] . '_question_' . $question['question_id'];
92  if (!isset($mappings[$mapping_key]) || !$mappings[$mapping_key]) {
93  continue;
94  }
95  $question_ref_id = $question['ref_id'];
96  $question_obj_id = $question['obj_id'];
97  $question_qst_id = $question['question_id'];
98  $new_ref_id = (int) $mappings[$question_ref_id];
99  $new_obj_id = $this->objectDataCache->lookupObjId($new_ref_id);
100 
101  if ($new_obj_id == $question_obj_id) {
102  $this->logger->info('Test has been linked. Keeping question id');
103  // Object has been linked
104  $new_question_id = $question_qst_id;
105  } else {
106  $new_question_info = $mappings[$question_ref_id . '_question_' . $question_qst_id];
107  $new_question_arr = explode('_', $new_question_info);
108  if (!isset($new_question_arr[2]) || !$new_question_arr[2]) {
109  $this->logger->debug('found invalid format of question id mapping: ' . print_r(
110  $new_question_arr,
111  true
112  ));
113  continue;
114  }
115  $new_question_id = $new_question_arr[2];
116  $this->logger->info('New question id is: ' . $new_question_id);
117  }
118 
119  ilLoggerFactory::getLogger('crs')->debug('Copying question assignments');
120  $new_question = new ilCourseObjectiveQuestion($a_new_objective);
121  $new_question->setTestRefId($new_ref_id);
122  $new_question->setTestObjId($new_obj_id);
123  $new_question->setQuestionId($new_question_id);
124  $new_question->add();
125  }
126 
127  // Copy tests
128  foreach ($this->getTests() as $test) {
129  if (!isset($mappings["$test[ref_id]"])) {
130  continue;
131  }
132  $new_test_id = $mappings["$test[ref_id]"];
133 
134  $query = "UPDATE crs_objective_tst " .
135  "SET tst_status = " . $this->db->quote($test['tst_status'], 'integer') . ", " .
136  "tst_limit_p = " . $this->db->quote($test['tst_limit'], 'integer') . " " .
137  "WHERE objective_id = " . $this->db->quote($a_new_objective, 'integer') . " " .
138  "AND ref_id = " . $this->db->quote($new_test_id, 'integer');
139  $res = $this->db->manipulate($query);
140  }
141  }
142 
143  public static function _getAssignableTests(int $a_container_ref_id): array
144  {
145  global $DIC;
146 
147  $tree = $DIC->repositoryTree();
148  return $tree->getSubTree($tree->getNodeData($a_container_ref_id), true, ['tst']);
149  }
150 
151  // ######################################################## Methods for test table
152  public function setTestStatus(int $a_status): void
153  {
154  $this->tst_status = $a_status;
155  }
156 
157  public function getTestStatus(): int
158  {
159  return $this->tst_status;
160  }
161 
162  public function setTestSuggestedLimit(int $a_limit): void
163  {
164  $this->tst_limit = $a_limit;
165  }
166 
167  public function getTestSuggestedLimit(): int
168  {
169  return $this->tst_limit;
170  }
171 
172  public function __addTest(): void
173  {
174  $query = "UPDATE crs_objective_tst " .
175  "SET tst_status = " . $this->db->quote($this->getTestStatus(), 'integer') . " " .
176  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " " .
177  "AND ref_id = " . $this->db->quote($this->getTestRefId(), 'integer') . " ";
178  $res = $this->db->manipulate($query);
179 
180  // CHECK if entry already exists
181  $query = "SELECT * FROM crs_objective_tst " .
182  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " " .
183  "AND ref_id = " . $this->db->quote($this->getTestRefId(), 'integer') . "";
184 
185  $res = $this->db->query($query);
186  if ($res->numRows()) {
187  return;
188  }
189 
190  // Check for existing limit
191  $query = "SELECT tst_limit_p FROM crs_objective_tst " .
192  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " " .
193  "AND tst_status = " . $this->db->quote($this->getTestStatus(), 'integer') . " ";
194  $res = $this->db->query($query);
195  $limit_in_db = null;
196  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
197  $limit_in_db = (int) $row->tst_limit_p;
198  }
199  // Select correct limit
200  $limit = 100;
201  if (is_null($limit_in_db) && $this->tst_limit > 0 && $this->tst_limit <= 100) {
202  $limit = $this->tst_limit;
203  }
204  if (!is_null($limit_in_db)) {
205  $limit = $limit_in_db;
206  }
207 
208  $next_id = $this->db->nextId('crs_objective_tst');
209  $query = "INSERT INTO crs_objective_tst (test_objective_id,objective_id,ref_id,obj_id,tst_status,tst_limit_p) " .
210  "VALUES( " .
211  $this->db->quote($next_id, 'integer') . ", " .
212  $this->db->quote($this->getObjectiveId(), 'integer') . ", " .
213  $this->db->quote($this->getTestRefId(), 'integer') . ", " .
214  $this->db->quote($this->getTestObjId(), 'integer') . ", " .
215  $this->db->quote($this->getTestStatus(), 'integer') . ", " .
216  $this->db->quote($limit, 'integer') . " " .
217  ")";
218  $res = $this->db->manipulate($query);
219  }
220 
221  public function __deleteTest(int $a_test_ref_id): void
222  {
223  // Delete questions
224  $query = "DELETE FROM crs_objective_qst " .
225  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " " .
226  "AND ref_id = " . $this->db->quote($a_test_ref_id, 'integer') . " ";
227  $res = $this->db->manipulate($query);
228 
229  // delete tst entries
230  $query = "DELETE FROM crs_objective_tst " .
231  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " " .
232  "AND ref_id = " . $this->db->quote($a_test_ref_id, 'integer') . " ";
233  $res = $this->db->manipulate($query);
234  unset($this->tests[$a_test_ref_id]);
235  }
236 
237  public static function _updateTestLimits(int $a_objective_id, int $a_status, int $a_limit): void
238  {
239  global $DIC;
240 
241  $ilDB = $DIC['ilDB'];
242 
243  $query = "UPDATE crs_objective_tst " .
244  "SET tst_limit_p = " . $ilDB->quote($a_limit, 'integer') . " " .
245  "WHERE tst_status = " . $ilDB->quote($a_status, 'integer') . " " .
246  "AND objective_id = " . $ilDB->quote($a_objective_id, 'integer');
247  $res = $ilDB->manipulate($query);
248  }
249 
250  public function updateTest(int $a_objective_id): void
251  {
252  $query = "UPDATE crs_objective_tst " .
253  "SET tst_status = " . $this->db->quote($this->getTestStatus(), 'integer') . ", " .
254  "tst_limit_p = " . $this->db->quote($this->getTestSuggestedLimit(), 'integer') . " " .
255  "WHERE test_objective_id = " . $this->db->quote($a_objective_id, 'integer') . "";
256  $res = $this->db->manipulate($query);
257  }
258 
259  public function getTests(): array
260  {
261  $query = "SELECT * FROM crs_objective_tst cot " .
262  "JOIN object_data obd ON cot.obj_id = obd.obj_id " .
263  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " " .
264  "ORDER BY title ";
265 
266  $res = $this->db->query($query);
267  $tests = [];
268  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
269  $test['test_objective_id'] = (int) $row->test_objective_id;
270  $test['objective_id'] = (int) $row->objective_id;
271  $test['ref_id'] = (int) $row->ref_id;
272  $test['obj_id'] = (int) $row->obj_id;
273  $test['tst_status'] = (int) $row->tst_status;
274  $test['tst_limit'] = (int) $row->tst_limit_p;
275  $test['title'] = (string) $row->title;
276 
277  $tests[] = $test;
278  }
279  return $tests;
280  }
281 
282  public function getSelfAssessmentTests(): array
283  {
284  $self = [];
285  foreach ($this->tests as $test) {
286  if ($test['status'] == self::TYPE_SELF_ASSESSMENT) {
287  $self[] = $test;
288  }
289  }
290  return $self;
291  }
292 
293  public function getFinalTests(): array
294  {
295  $final = [];
296  foreach ($this->tests as $test) {
297  if ($test['status'] == self::TYPE_FINAL_TEST) {
298  $final[] = $test;
299  }
300  }
301  return $final;
302  }
303 
304  public static function _getTest(int $a_test_objective_id): array
305  {
306  global $DIC;
307 
308  $ilDB = $DIC->database();
309  $query = "SELECT * FROM crs_objective_tst " .
310  "WHERE test_objective_id = " . $ilDB->quote($a_test_objective_id, 'integer') . " ";
311 
312  $res = $ilDB->query($query);
313  $test = [];
314  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
315  $test['test_objective_id'] = (int) $row->test_objective_id;
316  $test['objective_id'] = (int) $row->objective_id;
317  $test['ref_id'] = (int) $row->ref_id;
318  $test['obj_id'] = (int) $row->obj_id;
319  $test['tst_status'] = (int) $row->tst_status;
320  $test['tst_limit'] = (int) $row->tst_limit_p;
321  }
322 
323  return $test;
324  }
325 
326  public function getQuestions(): array
327  {
328  return $this->questions;
329  }
330 
331  public function getSelfAssessmentQuestions(): array
332  {
333  $self = [];
334  foreach ($this->questions as $question) {
335  if ($question['test_type'] == self::TYPE_SELF_ASSESSMENT) {
336  $self[] = $question;
337  }
338  }
339  return $self;
340  }
341 
342  public function getSelfAssessmentPoints(): int
343  {
344  $points = 0;
345  foreach ($this->getSelfAssessmentQuestions() as $question) {
346  $points += $question['points'];
347  }
348  return $points;
349  }
350 
351  public function getFinalTestPoints(): int
352  {
353  $points = 0;
354  foreach ($this->getFinalTestQuestions() as $question) {
355  $points += $question['points'];
356  }
357  return $points;
358  }
359 
360  public function isSelfAssessmentQuestion(int $a_question_id): bool
361  {
362  foreach ($this->questions as $question) {
363  if ($question['question_id'] == $a_question_id) {
364  return $question['test_type'] === self::TYPE_SELF_ASSESSMENT;
365  }
366  }
367  return false;
368  }
369 
370  public function isFinalTestQuestion(int $a_question_id): bool
371  {
372  foreach ($this->questions as $question) {
373  if ($question['question_id'] == $a_question_id) {
374  return $question['test_type'] === self::TYPE_FINAL_TEST;
375  }
376  }
377  return false;
378  }
379 
380  public function getFinalTestQuestions(): array
381  {
382  $final = [];
383  foreach ($this->questions as $question) {
384  if ($question['test_type'] == self::TYPE_FINAL_TEST) {
385  $final[] = $question;
386  }
387  }
388  return $final;
389  }
390 
391  public function getQuestionsOfTest(int $a_test_id): array
392  {
393  $questions = [];
394  foreach ($this->getQuestions() as $qst) {
395  if ($a_test_id == $qst['obj_id']) {
396  $questions[] = $qst;
397  }
398  }
399  return $questions;
400  }
401 
402  public function getQuestion(int $question_id): array
403  {
404  if ($this->questions[$question_id]) {
405  return $this->questions[$question_id];
406  } else {
407  return array();
408  }
409  }
410 
411  public function getObjectiveId(): int
412  {
413  return $this->objective_id;
414  }
415 
416  public function setTestRefId(int $a_ref_id): void
417  {
418  $this->tst_ref_id = $a_ref_id;
419  }
420 
421  public function getTestRefId(): int
422  {
423  return $this->tst_ref_id;
424  }
425 
426  public function setTestObjId(int $a_obj_id): void
427  {
428  $this->tst_obj_id = $a_obj_id;
429  }
430 
431  public function getTestObjId(): int
432  {
433  return $this->tst_obj_id;
434  }
435 
436  public function setQuestionId(int $a_question_id): void
437  {
438  $this->question_id = $a_question_id;
439  }
440 
441  public function getQuestionId(): int
442  {
443  return $this->question_id;
444  }
445 
446  public function getMaxPointsByObjective(): int
447  {
448  $points = 0;
449  foreach ($this->getQuestions() as $question) {
450  $tmp_test = ilObjectFactory::getInstanceByRefId($question['ref_id']);
451  $tmp_question = ilObjTest::_instanciateQuestion($question['question_id']);
452  $points += $tmp_question->getMaximumPoints();
453  }
454  return $points;
455  }
456 
457  public function getMaxPointsByTest(int $a_test_ref_id): int
458  {
459  $points = 0;
460  $tmp_test = ilObjectFactory::getInstanceByRefId($a_test_ref_id);
461  foreach ($this->getQuestions() as $question) {
462  if ($question['ref_id'] == $a_test_ref_id) {
463  $tmp_question = ilObjTest::_instanciateQuestion($question['question_id']);
464  $points += $tmp_question->getMaximumPoints();
465  }
466  }
467  return $points;
468  }
469 
470  public static function _lookupMaximumPointsOfQuestion(int $a_question_id): float
471  {
472  global $DIC;
473  return $DIC->testQuestion()->getGeneralQuestionProperties($a_question_id)->getAvailablePoints();
474  }
475 
476  public function getNumberOfQuestionsByTest(int $a_test_ref_id): int
477  {
478  $counter = 0;
479  foreach ($this->getQuestions() as $question) {
480  if ($question['ref_id'] == $a_test_ref_id) {
481  ++$counter;
482  }
483  }
484  return $counter;
485  }
486 
487  public function getQuestionsByTest(int $a_test_ref_id): array
488  {
489  $qst = [];
490  foreach ($this->getQuestions() as $question) {
491  if ($question['ref_id'] == $a_test_ref_id) {
492  $qst[] = $question['question_id'];
493  }
494  }
495  return $qst;
496  }
497 
498  public function updateLimits(): void
499  {
500  $points = 0;
501  foreach ($this->tests as $test_data) {
502  switch ($test_data['status']) {
503  case self::TYPE_SELF_ASSESSMENT:
504  $points = $this->getSelfAssessmentPoints();
505  break;
506 
507  case self::TYPE_FINAL_TEST:
508  $points = $this->getFinalTestPoints();
509  break;
510  }
511  if ($test_data['limit'] == -1 || $test_data['limit'] > $points) {
512  switch ($test_data['status']) {
513  case self::TYPE_SELF_ASSESSMENT:
514  $points = $this->getSelfAssessmentPoints();
515  break;
516 
517  case self::TYPE_FINAL_TEST:
518  $points = $this->getFinalTestPoints();
519  break;
520  }
521  $query = "UPDATE crs_objective_tst " .
522  "SET tst_limit = " . $this->db->quote($points, 'integer') . " " .
523  "WHERE test_objective_id = " . $this->db->quote($test_data['test_objective_id'], 'integer') . " ";
524  $res = $this->db->manipulate($query);
525  }
526  }
527  }
528 
529  public function add(): void
530  {
531  $query = "DELETE FROM crs_objective_qst " .
532  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " " .
533  "AND question_id = " . $this->db->quote($this->getQuestionId(), 'integer') . " ";
534  $res = $this->db->manipulate($query);
535 
536  $next_id = $this->db->nextId('crs_objective_qst');
537  $query = "INSERT INTO crs_objective_qst (qst_ass_id, objective_id,ref_id,obj_id,question_id) " .
538  "VALUES( " .
539  $this->db->quote($next_id, 'integer') . ", " .
540  $this->db->quote($this->getObjectiveId(), 'integer') . ", " .
541  $this->db->quote($this->getTestRefId(), 'integer') . ", " .
542  $this->db->quote($this->getTestObjId(), 'integer') . ", " .
543  $this->db->quote($this->getQuestionId(), 'integer') .
544  ")";
545  $res = $this->db->manipulate($query);
546 
547  $this->__addTest();
548  $this->__read();
549  }
550 
551  public function delete(int $qst_id): void
552  {
553  if (!$qst_id) {
554  return;
555  }
556 
557  $query = "SELECT * FROM crs_objective_qst " .
558  "WHERE qst_ass_id = " . $this->db->quote($qst_id, 'integer') . " ";
559 
560  $test_rid = $test_oid = 0;
561  $res = $this->db->query($query);
562  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
563  $test_rid = (int) $row->ref_id;
564  $test_oid = (int) $row->obj_id;
565  }
566 
567  $query = "DELETE FROM crs_objective_qst " .
568  "WHERE qst_ass_id = " . $this->db->quote($qst_id, 'integer') . " ";
569  $res = $this->db->manipulate($query);
570 
571  // delete test if it was the last question
572  $query = "SELECT * FROM crs_objective_qst " .
573  "WHERE ref_id = " . $this->db->quote($test_rid, 'integer') . " " .
574  "AND obj_id = " . $this->db->quote($test_oid, 'integer') . " " .
575  "AND objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " ";
576 
577  $res = $this->db->query($query);
578  if ($res->numRows() === 0) {
579  $this->__deleteTest($test_rid);
580  }
581  }
582 
583  // begin-patch lok
584  public static function deleteTest(int $a_tst_ref_id): void
585  {
586  global $DIC;
587 
588  $ilDB = $DIC->database();
589  $query = 'DELETE FROM crs_objective_tst ' .
590  'WHERE ref_id = ' . $ilDB->quote($a_tst_ref_id, 'integer');
591  $ilDB->manipulate($query);
592 
593  $query = 'DELETE FROM crs_objective_qst ' .
594  'WHERE ref_id = ' . $ilDB->quote($a_tst_ref_id, 'integer');
595  $ilDB->manipulate($query);
596  }
597 
598  public function deleteByTestType(int $a_type): void
599  {
600  // Read tests by type
601  $deletable_refs = array();
602  foreach ($this->tests as $tst_data) {
603  if ($tst_data['status'] == $a_type) {
604  $deletable_refs[] = $tst_data['ref_id'];
605  }
606  }
607 
608  $query = 'DELETE from crs_objective_tst ' .
609  'WHERE objective_id = ' . $this->db->quote($this->getObjectiveId(), 'integer') . ' ' .
610  'AND tst_status = ' . $this->db->quote($a_type, 'integer');
611  $this->db->manipulate($query);
612 
613  $query = 'DELETE from crs_objective_tst ' .
614  'WHERE objective_id = ' . $this->db->quote($this->getObjectiveId(), 'integer') . ' ' .
615  'AND ' . $this->db->in('ref_id', $deletable_refs, false, 'integer');
616  $this->db->manipulate($query);
617  }
618 
619  public function deleteAll(): void
620  {
621  $query = "DELETE FROM crs_objective_qst " .
622  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " ";
623  $res = $this->db->manipulate($query);
624 
625  $query = "DELETE FROM crs_objective_tst " .
626  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " ";
627  $res = $this->db->manipulate($query);
628  }
629 
630  public function __read(): void
631  {
632  $container_ref_ids = ilObject::_getAllReferences(ilCourseObjective::_lookupContainerIdByObjectiveId($this->objective_id));
633  $container_ref_id = current($container_ref_ids);
634 
635  // Read test data
636  $query = "SELECT * FROM crs_objective_tst " .
637  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " ";
638  $res = $this->db->query($query);
639  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
640  $this->tests[(int) $row->ref_id]['test_objective_id'] = (int) $row->test_objective_id;
641  $this->tests[(int) $row->ref_id]['ref_id'] = (int) $row->ref_id;
642  $this->tests[(int) $row->ref_id]['obj_id'] = (int) $row->obj_id;
643  $this->tests[(int) $row->ref_id]['status'] = (int) $row->tst_status;
644  $this->tests[(int) $row->ref_id]['limit'] = (int) $row->tst_limit_p;
645  }
646 
647  $this->questions = array();
648  $query = "SELECT * FROM crs_objective_qst coq " .
649  "JOIN qpl_questions qq ON coq.question_id = qq.question_id " .
650  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " " .
651  "ORDER BY title";
652 
653  $res = $this->db->query($query);
654  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
655  if (!array_key_exists((int) $row->ref_id, $this->tests)) {
656  $this->__deleteTest((int) $row->ref_id);
657  continue;
658  }
659  if (!$this->tree->isInTree((int) $row->ref_id) || !$this->tree->isGrandChild(
660  $container_ref_id,
661  (int) $row->ref_id
662  )) {
663  $this->__deleteTest((int) $row->ref_id);
664  continue;
665  }
666  if (($question = ilObjTest::_instanciateQuestion((int) $row->question_id)) === null) {
667  $this->delete((int) $row->question_id);
668  continue;
669  }
670  $qst['ref_id'] = (int) $row->ref_id;
671  $qst['obj_id'] = (int) $row->obj_id;
672  $qst['question_id'] = (int) $row->question_id;
673  $qst['qst_ass_id'] = (int) $row->qst_ass_id;
674  $qst['title'] = $question->getTitle();
675  $qst['description'] = $question->getComment();
676  $qst['test_type'] = (int) $this->tests[(int) $row->ref_id]['status'];
677  $qst['points'] = (float) $question->getPoints();
678 
679  $this->questions[(int) $row->qst_ass_id] = $qst;
680  }
681  }
682 
683  public static function _hasTests(int $a_course_id): bool
684  {
685  global $DIC;
686 
687  $ilDB = $DIC['ilDB'];
688 
689  $query = "SELECT co.objective_id FROM crs_objectives co JOIN " .
690  "crs_objective_tst cot ON co.objective_id = cot.objective_id " .
691  "WHERE crs_id = " . $ilDB->quote($a_course_id, 'integer') . " ";
692  $res = $ilDB->query($query);
693  return (bool) $res->numRows();
694  }
695 
696  public static function _isAssigned(int $a_objective_id, int $a_tst_ref_id, int $a_question_id): int
697  {
698  global $DIC;
699 
700  $ilDB = $DIC->database();
701  $query = "SELECT crs_qst.objective_id objective_id FROM crs_objective_qst crs_qst, crs_objectives crs_obj " .
702  "WHERE crs_qst.objective_id = crs_obj.objective_id " .
703  "AND crs_qst.objective_id = " . $ilDB->quote($a_objective_id, 'integer') . " " .
704  "AND ref_id = " . $ilDB->quote($a_tst_ref_id, 'integer') . " " .
705  "AND question_id = " . $ilDB->quote($a_question_id, 'integer') . " ";
706 
707  $res = $ilDB->query($query);
708  $objective_id = 0;
709  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
710  $objective_id = (int) $row->objective_id;
711  }
712  return $objective_id;
713  }
714 
715  public static function lookupQuestionsByObjective(int $a_test_id, int $a_objective): array
716  {
717  global $DIC;
718 
719  $ilDB = $DIC->database();
720  $query = 'SELECT question_id FROM crs_objective_qst ' .
721  'WHERE objective_id = ' . $ilDB->quote($a_objective, 'integer') . ' ' .
722  'AND obj_id = ' . $ilDB->quote($a_test_id, 'integer');
723  $res = $ilDB->query($query);
724 
725  $questions = array();
726  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
727  $questions[] = $row->question_id;
728  }
729  return $questions;
730  }
731 
732  public static function loookupTestLimit(int $a_test_id, int $a_objective_id): int
733  {
734  global $DIC;
735 
736  $ilDB = $DIC['ilDB'];
737  $query = 'SELECT tst_limit_p FROM crs_objective_tst ' .
738  'WHERE objective_id = ' . $ilDB->quote($a_objective_id, 'integer') . ' ' .
739  'AND obj_id = ' . $ilDB->quote($a_test_id, 'integer');
740  $res = $ilDB->query($query);
741  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
742  return (int) $row->tst_limit_p;
743  }
744  return 0;
745  }
746 
747  public function toXml(ilXmlWriter $writer): void
748  {
749  foreach ($this->getTests() as $test) {
750  $writer->xmlStartTag(
751  'Test',
752  array(
753  'type' => ilLOXmlWriter::TYPE_TST_ALL,
754  'refId' => $test['ref_id'],
755  'testType' => $test['tst_status'],
756  'limit' => $test['tst_limit']
757  )
758  );
759 
760  // questions
761  foreach ($this->getQuestionsByTest($test['ref_id']) as $question_id) {
762  $writer->xmlElement('Question', array('id' => $question_id));
763  }
764  $writer->xmlEndTag('Test');
765  }
766  }
767 
768  // end-patch lok
769 }
$res
Definition: ltiservices.php:66
static _isTestAssignedToObjective(int $a_test_id, int $a_objective_id)
static _getAssignableTests(int $a_container_ref_id)
getNodeData(int $a_node_id, ?int $a_tree_pk=null)
get all information of a node.
static getLogger(string $a_component_id)
Get component logger.
static _lookupMaximumPointsOfQuestion(int $a_question_id)
static lookupQuestionsByObjective(int $a_test_id, int $a_objective)
static _getAllReferences(int $id)
get all reference ids for object ID
static _lookupContainerIdByObjectiveId(int $a_objective_id)
static loookupTestLimit(int $a_test_id, int $a_objective_id)
static _instanciateQuestion($question_id)
Creates an instance of a question with a given question id.
xmlEndTag(string $tag)
Writes an endtag.
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static _getTest(int $a_test_objective_id)
static _updateTestLimits(int $a_objective_id, int $a_status, int $a_limit)
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
static _isAssigned(int $a_objective_id, int $a_tst_ref_id, int $a_question_id)
global $DIC
Definition: shib_login.php:26
cloneDependencies(int $a_new_objective, int $a_copy_id)
xmlStartTag(string $tag, ?array $attrs=null, bool $empty=false, bool $encode=true, bool $escape=true)
Writes a starttag.
static _getInstance(int $a_copy_id)
xmlElement(string $tag, $attrs=null, $data=null, $encode=true, $escape=true)
Writes a basic element (no children, just textual content)
getSubTree(array $a_node, bool $a_with_data=true, array $a_type=[])
get all nodes in the subtree under specified node
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...