ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilCourseObjective.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=0);
4 
28 {
29  protected ilObject $course_obj;
30 
31  private int $objective_id = 0;
32  private string $title = '';
33  private string $description = '';
34  private int $position;
35  private bool $active = true;
36  private int $passes = 0;
37  private int $created = 0;
38 
39  protected ilDBInterface $db;
40  protected ilLogger $logger;
41 
42  public function __construct(ilObject $course_obj, int $a_objective_id = 0)
43  {
44  global $DIC;
45 
46  $this->db = $DIC->database();
47  $this->logger = $DIC->logger()->crs();
48 
49  $this->course_obj = $course_obj;
50  $this->objective_id = $a_objective_id;
51  if ($this->objective_id) {
52  $this->__read();
53  }
54  }
55 
56  public function getCourse(): ilObject
57  {
58  return $this->course_obj;
59  }
60 
61  public static function _lookupContainerIdByObjectiveId(int $a_objective_id): int
62  {
63  global $DIC;
64 
65  $ilDB = $DIC->database();
66  $query = "SELECT crs_id FROM crs_objectives " .
67  "WHERE objective_id = " . $ilDB->quote($a_objective_id, 'integer');
68  $res = $ilDB->query($query);
69  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
70  return (int) $row->crs_id;
71  }
72  return 0;
73  }
74 
75  public static function _getCountObjectives(int $a_obj_id, bool $a_activated_only = false): int
76  {
77  return count(ilCourseObjective::_getObjectiveIds($a_obj_id, $a_activated_only));
78  }
79 
80  public static function lookupMaxPasses(int $a_objective_id): int
81  {
82  global $DIC;
83 
84  $ilDB = $DIC['ilDB'];
85  $query = 'SELECT passes from crs_objectives ' .
86  'WHERE objective_id = ' . $ilDB->quote($a_objective_id, 'integer');
87  $res = $ilDB->query($query);
88  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
89  return (int) $row->passes;
90  }
91  return 0;
92  }
93 
97  public static function lookupObjectiveTitle(int $a_objective_id, bool $a_add_description = false)
98  {
99  global $DIC;
100 
101  $ilDB = $DIC->database();
102  $query = 'SELECT title,description from crs_objectives ' .
103  'WHERE objective_id = ' . $ilDB->quote($a_objective_id, 'integer');
104  $res = $ilDB->query($query);
105  while ($row = $ilDB->fetchAssoc($res)) {
106  if (!$a_add_description) {
107  return $row['title'];
108  } else {
109  return $row;
110  }
111  }
112  return "";
113  }
114 
115  public function ilClone(int $a_target_id, int $a_copy_id): void
116  {
117  $query = "SELECT * FROM crs_objectives " .
118  "WHERE crs_id = " . $this->db->quote($this->course_obj->getId(), 'integer') . ' ' .
119  "ORDER BY position ";
120  $res = $this->db->query($query);
121  if ($res->numRows() === 0) {
122  $this->logger->debug('.. no objectives found');
123  return;
124  }
125 
126  if (!is_object($new_course = ilObjectFactory::getInstanceByRefId($a_target_id, false))) {
127  $this->logger->warning('Cannot create course instance');
128  return;
129  }
130  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
131  $new_objective = new ilCourseObjective($new_course);
132  $new_objective->setTitle((string) $row->title);
133  $new_objective->setDescription((string) $row->description);
134  $new_objective->setActive((bool) $row->active);
135  $objective_id = $new_objective->add();
136  $this->logger->debug('Added new objective nr: ' . $objective_id);
137 
138  // Clone crs_objective_tst entries
139  $objective_qst = new ilCourseObjectiveQuestion((int) $row->objective_id);
140  $objective_qst->cloneDependencies($objective_id, $a_copy_id);
141 
142  $random_i = new ilLORandomTestQuestionPools(
143  $this->getCourse()->getId(),
144  (int) $row->objective_id,
146  0
147  );
148  $random_i->copy($a_copy_id, $new_course->getId(), $objective_id);
149 
150  $random_q = new ilLORandomTestQuestionPools(
151  $this->getCourse()->getId(),
152  (int) $row->objective_id,
154  0
155  );
156  $random_q->copy($a_copy_id, $new_course->getId(), $objective_id);
157 
158  $assignments = ilLOTestAssignments::getInstance($this->course_obj->getId());
159  $assignment_it = $assignments->getAssignmentByObjective(
160  (int) $row->objective_id,
162  );
163  if ($assignment_it) {
164  $assignment_it->cloneSettings($a_copy_id, $new_course->getId(), $objective_id);
165  }
166 
167  $assignment_qt = $assignments->getAssignmentByObjective(
168  (int) $row->objective_id,
170  );
171  if ($assignment_qt) {
172  $assignment_qt->cloneSettings($a_copy_id, $new_course->getId(), $objective_id);
173  }
174 
175  $this->logger->debug('Finished copying question dependencies');
176 
177  // Clone crs_objective_lm entries (assigned course materials)
178  $objective_material = new ilCourseObjectiveMaterials((int) $row->objective_id);
179  $objective_material->cloneDependencies($objective_id, $a_copy_id);
180  }
181  $this->logger->debug('Finished copying objectives');
182  }
183 
184  public function setActive(bool $a_stat): void
185  {
186  $this->active = $a_stat;
187  }
188 
189  public function isActive(): bool
190  {
191  return $this->active;
192  }
193 
194  public function setPasses(int $a_passes): void
195  {
196  $this->passes = $a_passes;
197  }
198 
199  public function getPasses(): int
200  {
201  return $this->passes;
202  }
203 
204  public function arePassesLimited(): bool
205  {
206  return $this->passes > 0;
207  }
208 
209  // end-patch lok
210 
211  public function setTitle(string $a_title): void
212  {
213  $this->title = $a_title;
214  }
215 
216  public function getTitle(): string
217  {
218  return $this->title;
219  }
220 
221  public function setDescription(string $a_description): void
222  {
223  $this->description = $a_description;
224  }
225 
226  public function getDescription(): string
227  {
228  return $this->description;
229  }
230 
231  public function setObjectiveId(int $a_objective_id): void
232  {
233  $this->objective_id = $a_objective_id;
234  }
235 
236  public function getObjectiveId(): int
237  {
238  return $this->objective_id;
239  }
240 
241  public function setPosition(int $a_pos): void
242  {
243  $this->position = $a_pos;
244  }
245 
246  public function add(): int
247  {
248  $next_id = $this->db->nextId('crs_objectives');
249  $query = "INSERT INTO crs_objectives (crs_id,objective_id,active,title,description,position,created,passes) " .
250  "VALUES( " .
251  $this->db->quote($this->course_obj->getId(), 'integer') . ", " .
252  $this->db->quote($next_id, 'integer') . ", " .
253  $this->db->quote($this->isActive(), 'integer') . ', ' .
254  $this->db->quote($this->getTitle(), 'text') . ", " .
255  $this->db->quote($this->getDescription(), 'text') . ", " .
256  $this->db->quote($this->__getLastPosition() + 1, 'integer') . ", " .
257  $this->db->quote(time(), 'integer') . ", " .
258  $this->db->quote($this->getPasses(), 'integer') . ' ' .
259  ")";
260  $res = $this->db->manipulate($query);
261 
262  // refresh learning progress status after adding new objective
263  ilLPStatusWrapper::_refreshStatus($this->course_obj->getId());
264  return $this->objective_id = $next_id;
265  }
266 
267  public function update(): void
268  {
269  $query = "UPDATE crs_objectives " .
270  "SET title = " . $this->db->quote($this->getTitle(), 'text') . ", " .
271  'active = ' . $this->db->quote($this->isActive(), 'integer') . ', ' .
272  "description = " . $this->db->quote($this->getDescription(), 'text') . ", " .
273  'passes = ' . $this->db->quote($this->getPasses(), 'integer') . ' ' .
274  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " " .
275  "AND crs_id = " . $this->db->quote($this->course_obj->getId(), 'integer') . " ";
276  $res = $this->db->manipulate($query);
277  }
278 
279  public function writePosition(int $a_position): void
280  {
281  $query = "UPDATE crs_objectives " .
282  "SET position = " . $this->db->quote((string) $a_position, 'integer') . " " .
283  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " ";
284  $res = $this->db->manipulate($query);
285  }
286 
287  public function validate(): bool
288  {
289  return (bool) strlen($this->getTitle());
290  }
291 
292  public function delete(): void
293  {
294  $tmp_obj_qst = new ilCourseObjectiveQuestion($this->getObjectiveId());
295  $tmp_obj_qst->deleteAll();
296 
297  $tmp_obj_lm = new ilCourseObjectiveMaterials($this->getObjectiveId());
298  $tmp_obj_lm->deleteAll();
299 
300  $query = "DELETE FROM crs_objectives " .
301  "WHERE crs_id = " . $this->db->quote($this->course_obj->getId(), 'integer') . " " .
302  "AND objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " ";
303  $res = $this->db->manipulate($query);
304 
305  // refresh learning progress status after deleting objective
306  ilLPStatusWrapper::_refreshStatus($this->course_obj->getId());
307  }
308 
309  public function moveUp(): void
310  {
311  if (!$this->getObjectiveId()) {
312  return;
313  }
314  // Stop if position is first
315  if ($this->__getPosition() == 1) {
316  return;
317  }
318 
319  $query = "UPDATE crs_objectives " .
320  "SET position = position + 1 " .
321  "WHERE position = " . $this->db->quote($this->__getPosition() - 1, 'integer') . " " .
322  "AND crs_id = " . $this->db->quote($this->course_obj->getId(), 'integer') . " ";
323  $res = $this->db->manipulate($query);
324 
325  $query = "UPDATE crs_objectives " .
326  "SET position = position - 1 " .
327  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " " .
328  "AND crs_id = " . $this->db->quote($this->course_obj->getId(), 'integer') . " ";
329  $res = $this->db->manipulate($query);
330 
331  $this->__read();
332  }
333 
334  public function moveDown(): void
335  {
336  if (!$this->getObjectiveId()) {
337  return;
338  }
339  // Stop if position is last
340  if ($this->__getPosition() == $this->__getLastPosition()) {
341  return;
342  }
343 
344  $query = "UPDATE crs_objectives " .
345  "SET position = position - 1 " .
346  "WHERE position = " . $this->db->quote($this->__getPosition() + 1, 'integer') . " " .
347  "AND crs_id = " . $this->db->quote($this->course_obj->getId(), 'integer') . " ";
348  $res = $this->db->manipulate($query);
349 
350  $query = "UPDATE crs_objectives " .
351  "SET position = position + 1 " .
352  "WHERE objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " " .
353  "AND crs_id = " . $this->db->quote($this->course_obj->getId(), 'integer') . " ";
354  $res = $this->db->manipulate($query);
355 
356  $this->__read();
357  }
358 
359  public function __setPosition(int $a_position): void
360  {
361  $this->position = $a_position;
362  }
363 
364  public function __getPosition(): int
365  {
366  return $this->position;
367  }
368 
369  public function __setCreated(int $a_created): void
370  {
371  $this->created = $a_created;
372  }
373 
374  public function __getCreated(): int
375  {
376  return $this->created;
377  }
378 
379  public function __read(): void
380  {
381  if ($this->getObjectiveId()) {
382  $query = "SELECT * FROM crs_objectives " .
383  "WHERE crs_id = " . $this->db->quote($this->course_obj->getId(), 'integer') . " " .
384  "AND objective_id = " . $this->db->quote($this->getObjectiveId(), 'integer') . " ";
385 
386  $res = $this->db->query($query);
387  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
388  // begin-patch lok
389  $this->setActive((bool) $row->active);
390  $this->setPasses((int) $row->passes);
391  // end-patch lok
392  $this->setObjectiveId((int) $row->objective_id);
393  $this->setTitle((string) $row->title);
394  $this->setDescription((string) $row->description);
395  $this->__setPosition((int) $row->position);
396  $this->__setCreated((int) $row->created);
397  }
398  }
399  }
400 
401  public function __getOrderColumn(): string
402  {
403  switch ($this->course_obj->getOrderType()) {
405  return 'ORDER BY position';
406 
408  return 'ORDER BY title';
409 
411  return 'ORDER BY create';
412  }
413  return '';
414  }
415 
416  public function __updateTop(): void
417  {
418  $query = "UPDATE crs_objectives " .
419  "SET position = position - 1 " .
420  "WHERE position > " . $this->db->quote($this->__getPosition(), 'integer') . " " .
421  "AND crs_id = " . $this->db->quote($this->course_obj->getId(), 'integer') . " ";
422  $res = $this->db->manipulate($query);
423  }
424 
425  public function __getLastPosition(): int
426  {
427  $query = "SELECT MAX(position) pos FROM crs_objectives " .
428  "WHERE crs_id = " . $this->db->quote($this->course_obj->getId(), 'integer') . " ";
429 
430  $res = $this->db->query($query);
431  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
432  return (int) $row->pos;
433  }
434  return 0;
435  }
436 
437  public static function _getObjectiveIds(int $course_id, bool $a_activated_only = false): array
438  {
439  global $DIC;
440 
441  $ilDB = $DIC['ilDB'];
442 
443  if ($a_activated_only) {
444  $query = "SELECT objective_id FROM crs_objectives " .
445  "WHERE crs_id = " . $ilDB->quote($course_id, 'integer') . " " .
446  'AND active = ' . $ilDB->quote(1, 'integer') . ' ' .
447  "ORDER BY position";
448  } else {
449  $query = "SELECT objective_id FROM crs_objectives " .
450  "WHERE crs_id = " . $ilDB->quote($course_id, 'integer') . " " .
451  "ORDER BY position";
452  }
453 
454  $res = $ilDB->query($query);
455  $ids = [];
456  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
457  $ids[] = $row->objective_id;
458  }
459  return $ids;
460  }
461 
462  public static function _deleteAll(int $course_id): void
463  {
464  global $DIC;
465 
466  $ilDB = $DIC['ilDB'];
467 
468  // begin-patch lok
469  $ids = ilCourseObjective::_getObjectiveIds($course_id, false);
470  // end-patch lok
471  if ($ids === []) {
472  return;
473  }
474 
475  $in = $ilDB->in('objective_id', $ids, false, 'integer');
476 
477  $query = "DELETE FROM crs_objective_lm WHERE " . $in;
478  $res = $ilDB->manipulate($query);
479 
480  $query = "DELETE FROM crs_objective_tst WHERE " . $in;
481  $res = $ilDB->manipulate($query);
482 
483  $query = "DELETE FROM crs_objective_qst WHERE " . $in;
484  $res = $ilDB->manipulate($query);
485 
486  $query = "DELETE FROM crs_objectives WHERE crs_id = " . $ilDB->quote($course_id, 'integer');
487  $res = $ilDB->manipulate($query);
488 
489  // refresh learning progress status after deleting objectives
491  }
492 
493  public function toXml(ilXmlWriter $writer): void
494  {
495  $writer->xmlStartTag(
496  'Objective',
497  array(
498  'online' => (int) $this->isActive(),
499  'position' => $this->position,
500  'id' => $this->getObjectiveId()
501  )
502  );
503  $writer->xmlElement('Title', array(), $this->getTitle());
504  $writer->xmlElement('Description', array(), $this->getDescription());
505 
506  // materials
507  $materials = new ilCourseObjectiveMaterials($this->getObjectiveId());
508  $materials->toXml($writer);
509 
510  // test/questions
511  $test = new ilCourseObjectiveQuestion($this->getObjectiveId());
512  $test->toXml($writer);
513 
514  $assignments = ilLOTestAssignments::getInstance($this->course_obj->getId());
515  $assignments->toXml($writer, $this->getObjectiveId());
516 
518 
519  $writer->xmlEndTag('Objective');
520  }
521 }
$res
Definition: ltiservices.php:69
toXml(ilXmlWriter $writer)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
writePosition(int $a_position)
static _getObjectiveIds(int $course_id, bool $a_activated_only=false)
static toXml(ilXmlWriter $writer, int $a_objective_id)
static _lookupContainerIdByObjectiveId(int $a_objective_id)
xmlEndTag(string $tag)
Writes an endtag.
global $DIC
Definition: feed.php:28
static _deleteAll(int $course_id)
class ilCourseObjectiveMaterials
static _getCountObjectives(int $a_obj_id, bool $a_activated_only=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
static lookupMaxPasses(int $a_objective_id)
static _refreshStatus(int $a_obj_id, ?array $a_users=null)
__construct(ilObject $course_obj, int $a_objective_id=0)
ilClone(int $a_target_id, int $a_copy_id)
$query
setDescription(string $a_description)
__setPosition(int $a_position)
static lookupObjectiveTitle(int $a_objective_id, bool $a_add_description=false)
setObjectiveId(int $a_objective_id)
static getInstance(int $a_container_id)
xmlStartTag(string $tag, ?array $attrs=null, bool $empty=false, bool $encode=true, bool $escape=true)
Writes a starttag.
xmlElement(string $tag, $attrs=null, $data=null, $encode=true, $escape=true)
Writes a basic element (no children, just textual content)
class ilcourseobjectiveQuestion