ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilPRGProgress.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
27class ilPRGProgress extends Node
28{
29 public const STATUS_IN_PROGRESS = 1;
30 public const STATUS_COMPLETED = 2;
31 public const STATUS_ACCREDITED = 3;
32 public const STATUS_NOT_RELEVANT = 4;
33 public const STATUS_FAILED = 5;
34
35 public static $STATUS = [
41 ];
42
43 public const COMPLETED_BY_SUBNODES = -2;
44
47
48 protected int $prg_obj_id;
49 protected int $points = 0;
50 protected int $points_cur = 0;
51 protected int $status = 4;
52 protected ?int $completion_by = null;
53 protected \DateTimeImmutable $last_change;
54 protected int $last_change_by = -1;
55 protected ?\DateTimeImmutable $assignment_date = null;
56 protected ?\DateTimeImmutable $completion_date = null;
57 protected ?\DateTimeImmutable $deadline = null;
58 protected ?\DateTimeImmutable $vq_date = null;
59 protected bool $invalidated = false;
60 protected bool $is_individual = false;
61
62
63 public function __construct(
64 int $prg_obj_id,
65 int $status = self::STATUS_NOT_RELEVANT
66 ) {
67 $this->prg_obj_id = $prg_obj_id;
68 $this->status = $status;
69 $this->last_change = new \DateTimeImmutable();
70 $this->assignment_date = new \DateTimeImmutable();
71 parent::__construct((string) $prg_obj_id, []);
72 }
73
74 public function getNodeId(): int
75 {
76 return $this->prg_obj_id;
77 }
78
79
80 public function getAmountOfPoints(): int
81 {
82 return $this->points;
83 }
84
85 public function withAmountOfPoints(int $points): self
86 {
87 if ($points < 0) {
88 throw new ilException("ilPRGProgress::setAmountOfPoints: "
89 . "Expected a number >= 0 as argument, got '$points'");
90 }
91
92 $clone = clone $this;
93 $clone->points = $points;
94 return $clone;
95 }
96
97 public function getCurrentAmountOfPoints(): int
98 {
99 return $this->points_cur;
100 }
101
102 public function withCurrentAmountOfPoints(int $points_cur): self
103 {
104 if ($points_cur < 0) {
105 throw new ilException("ilPRGProgress::setAmountOfPoints: "
106 . "Expected a number >= 0 as argument, got '$points'");
107 }
108
109 $clone = clone $this;
110 $clone->points_cur = $points_cur;
111 return $clone;
112 }
113
114 public function getStatus(): int
115 {
116 return $this->status;
117 }
118
119 public function withStatus(int $status): self
120 {
121 if (!in_array($status, self::$STATUS)) {
122 throw new ilException("No such status: " . "'$status'");
123 }
124
125 if (!$this->isTransitionAllowedTo($status)) {
126 throw new ilException(
127 "Changing progress with status " . $this->getStatus()
128 . " cannot change to status " . "'$status'"
129 . ' (progress_id: ' . $this->getId() . ')'
130 );
131 }
132
133 $clone = clone $this;
134 $clone->status = $status;
135 return $clone;
136 }
137
138 public function isTransitionAllowedTo(int $new_status): bool
139 {
140 return is_null($this->status) ||
141 $this->status === $new_status ||
142 in_array($new_status, self::getAllowedTargetStatusFor($this->status));
143 }
144
145 public static function getAllowedTargetStatusFor(int $status_from): array
146 {
147 switch ($status_from) {
149 return [
154 ];
156 return [
161 ];
163 return [
164 self::STATUS_IN_PROGRESS, // deaccriditation of sub-progress might revert completion,
166 ];
168 return [
170 self::STATUS_COMPLETED, // with re-calculation of deadline, progress might directly be completed.
172 ];
174 return[
176 ];
177 }
178
179 return [];
180 }
181
182 public function getLastChangeBy(): int
183 {
185 }
186
187 public function getLastChange(): \DateTimeImmutable
188 {
189 return $this->last_change;
190 }
191
192 public function withLastChange(
193 int $last_change_by,
194 \DateTimeImmutable $last_change
195 ): self {
196 $clone = clone $this;
197 $clone->last_change = $last_change;
198 $clone->last_change_by = $last_change_by;
199 return $clone;
200 }
201
202 public function getAssignmentDate(): ?\DateTimeImmutable
203 {
204 return $this->assignment_date;
205 }
206
207 public function withAssignmentDate(?\DateTimeImmutable $assignment_date): self
208 {
209 $clone = clone $this;
210 $clone->assignment_date = $assignment_date;
211 return $clone;
212 }
213
214 public function getCompletionDate(): ?\DateTimeImmutable
215 {
216 return $this->completion_date;
217 }
218
219 public function getCompletionBy(): ?int
220 {
221 return $this->completion_by;
222 }
223
224 public function withCompletion(
225 ?int $usr_or_obj_id = null,
226 ?\DateTimeImmutable $completion_date = null
227 ): self {
228 $clone = clone $this;
229 $clone->completion_by = $usr_or_obj_id;
230 $clone->completion_date = $completion_date;
231 return $clone;
232 }
233
234 public function getDeadline(): ?\DateTimeImmutable
235 {
236 return $this->deadline;
237 }
238
239 public function withDeadline(?\DateTimeImmutable $deadline = null): self
240 {
241 $clone = clone $this;
242 $clone->deadline = $deadline;
243 return $clone;
244 }
245
246 public function getValidityOfQualification(): ?\DateTimeImmutable
247 {
248 return $this->vq_date;
249 }
250
251 public function withValidityOfQualification(?\DateTimeImmutable $date = null): self
252 {
253 $clone = clone $this;
254 $clone->vq_date = $date;
255 return $clone;
256 }
257
258 public function hasIndividualModifications(): bool
259 {
260 return $this->is_individual;
261 }
262
263 public function withIndividualModifications(bool $individual): self
264 {
265 $clone = clone $this;
266 $clone->is_individual = $individual;
267 return $clone;
268 }
269
270 public function isSuccessful(): bool
271 {
272 return in_array(
273 $this->getStatus(),
274 [
275 self::STATUS_COMPLETED,
276 self::STATUS_ACCREDITED
277 ]
278 );
279 }
280
285 public function hasValidQualification(\DateTimeImmutable $now): ?bool
286 {
287 if (!$this->isSuccessful()) {
288 return null;
289 }
290 return (
291 is_null($this->getValidityOfQualification()) ||
292 $this->getValidityOfQualification()->format(self::DATE_FORMAT) >= $now->format(self::DATE_FORMAT)
293 );
294 }
295
296 public function isRelevant(): bool
297 {
298 return $this->getStatus() != self::STATUS_NOT_RELEVANT;
299 }
300
301 public function isFailed(): bool
302 {
303 return $this->getStatus() == self::STATUS_FAILED;
304 }
305
306 public function isAccredited(): bool
307 {
308 return $this->getStatus() == self::STATUS_ACCREDITED;
309 }
310
311 public function isInProgress(): bool
312 {
313 return $this->getStatus() == self::STATUS_IN_PROGRESS;
314 }
315
317 {
318 $sum = 0;
319 $children = $this->getSubnodes();
320 foreach ($children as $child_progress) {
321 if ($child_progress->isSuccessful()) {
322 $sum += $child_progress->getAmountOfPoints();
323 }
324 }
325 return $sum;
326 }
327
329 {
330 $sum = 0;
331 $children = $this->getSubnodes();
332 foreach ($children as $child_progress) {
333 if ($child_progress->isRelevant()) {
334 $sum += $child_progress->getAmountOfPoints();
335 }
336 }
337 return $sum;
338 }
339
340 public function invalidate(): self
341 {
342 if (!$this->vq_date) {
343 throw new ilException("may not invalidate non-expired progress (no invalidation date)");
344 }
345 if ($this->vq_date->format(self::DATE_FORMAT) > date(self::DATE_FORMAT)) {
346 $msg = $this->vq_date->format(self::DATE_FORMAT) . ' > ' . date(self::DATE_FORMAT);
347 throw new ilException("may not invalidate non-expired progress ($msg)");
348 }
349 return $this->withInvalidated(true);
350 }
351
352 public function isInvalidated(): bool
353 {
354 return $this->invalidated;
355 }
356
357 public function withInvalidated(bool $invalidated): self
358 {
359 $clone = clone $this;
360 $clone->invalidated = $invalidated;
361 return $clone;
362 }
363
364 public function markAccredited(\DateTimeImmutable $date, int $acting_usr_id): self
365 {
366 return $this
367 ->withStatus(self::STATUS_ACCREDITED)
368 ->withCompletion($acting_usr_id, $date)
369 ->withLastChange($acting_usr_id, $date);
370 }
371
372 public function unmarkAccredited(\DateTimeImmutable $date, int $acting_usr_id): self
373 {
374 return $this
375 ->withStatus(self::STATUS_IN_PROGRESS)
376 ->withCompletion(null, null)
377 ->withValidityOfQualification(null)
378 ->withLastChange($acting_usr_id, $date);
379 }
380
381 public function markFailed(\DateTimeImmutable $date, int $acting_usr_id): self
382 {
383 return $this
384 ->withStatus(self::STATUS_FAILED)
385 ->withCompletion(null, null)
386 ->withLastChange($acting_usr_id, $date);
387 }
388
389 public function markNotFailed(\DateTimeImmutable $date, int $acting_usr_id): self
390 {
391 return $this
392 ->withStatus(self::STATUS_IN_PROGRESS)
393 ->withCompletion(null, null)
394 ->withLastChange($acting_usr_id, $date);
395 }
396
397 public function succeed(\DateTimeImmutable $date, int $triggering_obj_id): self
398 {
399 return $this
400 ->withStatus(self::STATUS_COMPLETED)
401 ->withCompletion($triggering_obj_id, $date)
402 ->withLastChange($triggering_obj_id, $date);
403 }
404
405 public function markNotRelevant(\DateTimeImmutable $date, int $acting_usr_id): self
406 {
407 return $this
408 ->withStatus(self::STATUS_NOT_RELEVANT)
409 ->withLastChange($acting_usr_id, $date)
410 ->withValidityOfQualification(null)
411 ->withDeadline(null)
412 ->withCompletion(null, null)
413 ->withCurrentAmountOfPoints(0)
414 ->withIndividualModifications(true);
415 }
416
417 public function markRelevant(\DateTimeImmutable $date, int $acting_usr_id): self
418 {
419 return $this
420 ->withStatus(self::STATUS_IN_PROGRESS)
421 ->withCompletion(null, null)
422 ->withLastChange($acting_usr_id, $date)
423 ->withIndividualModifications(true);
424 }
425}
Base class for ILIAS Exception handling.
A Progress is the status of a user on a single node of an assignment; it is unique by assignment_id:u...
withLastChange(int $last_change_by, \DateTimeImmutable $last_change)
withCurrentAmountOfPoints(int $points_cur)
markFailed(\DateTimeImmutable $date, int $acting_usr_id)
DateTimeImmutable $deadline
markAccredited(\DateTimeImmutable $date, int $acting_usr_id)
hasValidQualification(\DateTimeImmutable $now)
There may be no qualification at all (since the PRG is not passed), or the qualification is valid or ...
DateTimeImmutable $last_change
withInvalidated(bool $invalidated)
withAmountOfPoints(int $points)
succeed(\DateTimeImmutable $date, int $triggering_obj_id)
withCompletion(?int $usr_or_obj_id=null, ?\DateTimeImmutable $completion_date=null)
withIndividualModifications(bool $individual)
isTransitionAllowedTo(int $new_status)
unmarkAccredited(\DateTimeImmutable $date, int $acting_usr_id)
DateTimeImmutable $assignment_date
withDeadline(?\DateTimeImmutable $deadline=null)
__construct(int $prg_obj_id, int $status=self::STATUS_NOT_RELEVANT)
withAssignmentDate(?\DateTimeImmutable $assignment_date)
withValidityOfQualification(?\DateTimeImmutable $date=null)
static getAllowedTargetStatusFor(int $status_from)
markRelevant(\DateTimeImmutable $date, int $acting_usr_id)
DateTimeImmutable $vq_date
markNotFailed(\DateTimeImmutable $date, int $acting_usr_id)
DateTimeImmutable $completion_date
withStatus(int $status)
markNotRelevant(\DateTimeImmutable $date, int $acting_usr_id)
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc