Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 85
0.00% covered (danger)
0.00%
0 / 30
CRAP
0.00% covered (danger)
0.00%
0 / 1
Task
0.00% covered (danger)
0.00%
0 / 85
0.00% covered (danger)
0.00%
0 / 30
2256
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 addElement
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 addTag
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getMedia
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addMedia
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isToAccount
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 isToGroup
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 isCCAccount
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 isCCGroup
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 getCreatedBy
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setCreatedBy
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getStatus
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setStatus
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getPriority
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setPriority
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 removeElement
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 removeTag
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getTags
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTag
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTaskElements
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 invertTaskElements
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTaskElement
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addAttribute
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAttributes
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 hasAttributeValue
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
20
 getAttribute
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 toArray
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
2
 jsonSerialize
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Jingga
4 *
5 * PHP Version 8.1
6 *
7 * @package   Modules\Tasks\Models
8 * @copyright Dennis Eichhorn
9 * @license   OMS License 2.0
10 * @version   1.0.0
11 * @link      https://jingga.app
12 */
13declare(strict_types=1);
14
15namespace Modules\Tasks\Models;
16
17use Modules\Admin\Models\Account;
18use Modules\Admin\Models\NullAccount;
19use Modules\Calendar\Models\Schedule;
20use Modules\Media\Models\Media;
21use Modules\Tag\Models\NullTag;
22use Modules\Tag\Models\Tag;
23use phpOMS\Stdlib\Base\Exception\InvalidEnumValue;
24
25/**
26 * Task class.
27 *
28 * @package Modules\Tasks\Models
29 * @license OMS License 2.0
30 * @link    https://jingga.app
31 * @since   1.0.0
32 */
33class Task implements \JsonSerializable
34{
35    /**
36     * ID.
37     *
38     * @var int
39     * @since 1.0.0
40     */
41    public int $id = 0;
42
43    /**
44     * Title.
45     *
46     * @var string
47     * @since 1.0.0
48     */
49    public string $title = '';
50
51    /**
52     * Redirect.
53     *
54     * Used as reference or for redirection when opened.
55     * This allows to open the task on a different page with a different layout if needed (e.g. ticket system, workflow, checklist, ...)
56     *
57     * @var string
58     * @since 1.0.0
59     */
60    public string $redirect = '';
61
62    /**
63     * Trigger
64     *
65     * Event trigger to execute on task change.
66     *
67     * @var string
68     * @since 1.0.0
69     */
70    public string $trigger = '';
71
72    /**
73     * Creator.
74     *
75     * @var Account
76     * @since 1.0.0
77     */
78    public Account $createdBy;
79
80    /**
81     * Created.
82     *
83     * @var \DateTimeImmutable
84     * @since 1.0.0
85     */
86    public \DateTimeImmutable $createdAt;
87
88    /**
89     * Description.
90     *
91     * @var string
92     * @since 1.0.0
93     */
94    public string $description = '';
95
96    /**
97     * Description raw.
98     *
99     * @var string
100     * @since 1.0.0
101     */
102    public string $descriptionRaw = '';
103
104    /**
105     * Type.
106     *
107     * @var int
108     * @since 1.0.0
109     */
110    public int $type = TaskType::SINGLE;
111
112    /**
113     * Status.
114     *
115     * @var int
116     * @since 1.0.0
117     */
118    public int $status = TaskStatus::OPEN;
119
120    /**
121     * Completion status
122     * @var int
123     * @since 1.0.0
124     */
125    public int $completion = -1;
126
127    /**
128     * Attributes.
129     *
130     * @var TaskAttribute[]
131     * @since 1.0.0
132     */
133    public array $attributes = [];
134
135    /**
136     * Task can be closed by user.
137     *
138     * Setting it to false will only allow other modules to close this task
139     *
140     * @var bool
141     * @since 1.0.0
142     */
143    public bool $isClosable = true;
144
145    /**
146     * Task can be edited by user.
147     *
148     * Setting it to false will only allow other modules to close this task
149     *
150     * @var bool
151     * @since 1.0.0
152     */
153    public bool $isEditable = true;
154
155    /**
156     * Start.
157     *
158     * @var null|\DateTime
159     * @since 1.0.0
160     */
161    public ?\DateTime $start = null;
162
163    /**
164     * Due.
165     *
166     * @var null|\DateTime
167     * @since 1.0.0
168     */
169    public ?\DateTime $due = null;
170
171    /**
172     * Done.
173     *
174     * @var null|\DateTime
175     * @since 1.0.0
176     */
177    public ?\DateTime $done = null;
178
179    /**
180     * Task elements.
181     *
182     * @var TaskElement[]
183     * @since 1.0.0
184     */
185    public array $taskElements = [];
186
187    /**
188     * Tags.
189     *
190     * @var Tag[]
191     * @since 1.0.0
192     */
193    public array $tags = [];
194
195    /**
196     * Schedule
197     *
198     * @var Schedule
199     * @since 1.0.0
200     */
201    public Schedule $schedule;
202
203    /**
204     * Priority
205     *
206     * @var int
207     * @since 1.0.0
208     */
209    public int $priority = TaskPriority::NONE;
210
211    /**
212     * Media files
213     *
214     * @var array
215     * @since 1.0.0
216     */
217    public array $media = [];
218
219    /**
220     * Constructor.
221     *
222     * @since 1.0.0
223     */
224    public function __construct()
225    {
226        $this->createdBy = new NullAccount();
227        $this->createdAt = new \DateTimeImmutable('now');
228        $this->schedule  = new Schedule();
229        $this->start     = new \DateTime('now');
230        $this->due       = new \DateTime('now');
231        $this->due->modify('+1 day');
232    }
233
234    /**
235     * Adding new task element.
236     *
237     * @param TaskElement $element Task element
238     *
239     * @return int
240     *
241     * @since 1.0.0
242     */
243    public function addElement(TaskElement $element) : int
244    {
245        $this->taskElements[] = $element;
246
247        \end($this->taskElements);
248        $key = (int) \key($this->taskElements);
249        \reset($this->taskElements);
250
251        return $key;
252    }
253
254    /**
255     * Adding new tag.
256     *
257     * @param Tag $tag Tag
258     *
259     * @return int
260     *
261     * @since 1.0.0
262     */
263    public function addTag(Tag $tag) : int
264    {
265        $this->tags[] = $tag;
266
267        \end($this->tags);
268        $key = (int) \key($this->tags);
269        \reset($this->tags);
270
271        return $key;
272    }
273
274    /**
275     * Get all media
276     *
277     * @return Media[]
278     *
279     * @since 1.0.0
280     */
281    public function getMedia() : array
282    {
283        return $this->media;
284    }
285
286    /**
287     * Add media
288     *
289     * @param Media $media Media to add
290     *
291     * @return void
292     *
293     * @since 1.0.0
294     */
295    public function addMedia(Media $media) : void
296    {
297        $this->media[] = $media;
298    }
299
300    /**
301     * Check if user is in to
302     *
303     * @param int $id User id
304     *
305     * @return bool
306     *
307     * @since 1.0.0
308     */
309    public function isToAccount(int $id) : bool
310    {
311        foreach ($this->taskElements as $element) {
312            if ($element->isToAccount($id)) {
313                return true;
314            }
315        }
316
317        return false;
318    }
319
320    /**
321     * Check if group is in to
322     *
323     * @param int $id Group id
324     *
325     * @return bool
326     *
327     * @since 1.0.0
328     */
329    public function isToGroup(int $id) : bool
330    {
331        foreach ($this->taskElements as $element) {
332            if ($element->isToGroup($id)) {
333                return true;
334            }
335        }
336
337        return false;
338    }
339
340    /**
341     * Check if user is in cc
342     *
343     * @param int $id User id
344     *
345     * @return bool
346     *
347     * @since 1.0.0
348     */
349    public function isCCAccount(int $id) : bool
350    {
351        foreach ($this->taskElements as $element) {
352            if ($element->isCCAccount($id)) {
353                return true;
354            }
355        }
356
357        return false;
358    }
359
360    /**
361     * Check if group is in cc
362     *
363     * @param int $id Group id
364     *
365     * @return bool
366     *
367     * @since 1.0.0
368     */
369    public function isCCGroup(int $id) : bool
370    {
371        foreach ($this->taskElements as $element) {
372            if ($element->isCCGroup($id)) {
373                return true;
374            }
375        }
376
377        return false;
378    }
379
380    /**
381     * Get created by
382     *
383     * @return Account
384     *
385     * @since 1.0.0
386     */
387    public function getCreatedBy() : Account
388    {
389        return $this->createdBy;
390    }
391
392    /**
393     * Set created by
394     *
395     * @param Account $account Created by
396     *
397     * @return void
398     *
399     * @since 1.0.0
400     */
401    public function setCreatedBy(Account $account) : void
402    {
403        $this->createdBy           = $account;
404        $this->schedule->createdBy = $account;
405    }
406
407    /**
408     * Get status
409     *
410     * @return int
411     *
412     * @since 1.0.0
413     */
414    public function getStatus() : int
415    {
416        return $this->status;
417    }
418
419    /**
420     * Set status
421     *
422     * @param int $status Task status
423     *
424     * @return void
425     *
426     * @throws InvalidEnumValue
427     *
428     * @since 1.0.0
429     */
430    public function setStatus(int $status) : void
431    {
432        if (!TaskStatus::isValidValue($status)) {
433            throw new InvalidEnumValue((string) $status);
434        }
435
436        $this->status = $status;
437    }
438
439    /**
440     * Get priority
441     *
442     * @return int
443     *
444     * @since 1.0.0
445     */
446    public function getPriority() : int
447    {
448        return $this->priority;
449    }
450
451    /**
452     * Set priority
453     *
454     * @param int $priority Task priority
455     *
456     * @return void
457     *
458     * @throws InvalidEnumValue
459     *
460     * @since 1.0.0
461     */
462    public function setPriority(int $priority) : void
463    {
464        if (!TaskPriority::isValidValue($priority)) {
465            throw new InvalidEnumValue((string) $priority);
466        }
467
468        $this->priority = $priority;
469    }
470
471    /**
472     * Remove Element from list.
473     *
474     * @param int $id Task element
475     *
476     * @return bool
477     *
478     * @since 1.0.0
479     */
480    public function removeElement($id) : bool
481    {
482        if (isset($this->taskElements[$id])) {
483            unset($this->taskElements[$id]);
484
485            return true;
486        }
487
488        return false;
489    }
490
491    /**
492     * Remove Tag from list.
493     *
494     * @param int $id Tag
495     *
496     * @return bool
497     *
498     * @since 1.0.0
499     */
500    public function removeTag($id) : bool
501    {
502        if (isset($this->tags[$id])) {
503            unset($this->tags[$id]);
504
505            return true;
506        }
507
508        return false;
509    }
510
511    /**
512     * Get task elements.
513     *
514     * @return Tag[]
515     *
516     * @since 1.0.0
517     */
518    public function getTags() : array
519    {
520        return $this->tags;
521    }
522
523    /**
524     * Get task elements.
525     *
526     * @param int $id Element id
527     *
528     * @return Tag
529     *
530     * @since 1.0.0
531     */
532    public function getTag(int $id) : Tag
533    {
534        return $this->tags[$id] ?? new NullTag();
535    }
536
537    /**
538     * Get task elements.
539     *
540     * @return TaskElement[]
541     *
542     * @since 1.0.0
543     */
544    public function getTaskElements() : array
545    {
546        return $this->taskElements;
547    }
548
549    /**
550     * Get task elements in inverted order.
551     *
552     * @return TaskElement[]
553     *
554     * @since 1.0.0
555     */
556    public function invertTaskElements() : array
557    {
558        return \array_reverse($this->taskElements);
559    }
560
561    /**
562     * Get task elements.
563     *
564     * @param int $id Element id
565     *
566     * @return TaskElement
567     *
568     * @since 1.0.0
569     */
570    public function getTaskElement(int $id) : TaskElement
571    {
572        return $this->taskElements[$id] ?? new NullTaskElement();
573    }
574
575    /**
576     * Get task type.
577     *
578     * @return int
579     *
580     * @since 1.0.0
581     */
582    public function getType() : int
583    {
584        return $this->type;
585    }
586
587    /**
588     * Set task type.
589     *
590     * @param int $type Task type
591     *
592     * @return void
593     *
594     * @since 1.0.0
595     */
596    public function setType(int $type = TaskType::SINGLE) : void
597    {
598        $this->type = $type;
599    }
600
601    /**
602     * Add attribute to item
603     *
604     * @param TaskAttribute $attribute Note
605     *
606     * @return void
607     *
608     * @since 1.0.0
609     */
610    public function addAttribute(TaskAttribute $attribute) : void
611    {
612        $this->attributes[] = $attribute;
613    }
614
615    /**
616     * Get attributes
617     *
618     * @return TaskAttribute[]
619     *
620     * @since 1.0.0
621     */
622    public function getAttributes() : array
623    {
624        return $this->attributes;
625    }
626
627    /**
628     * Has attribute value
629     *
630     * @param string $attrName  Attribute name
631     * @param mixed  $attrValue Attribute value
632     *
633     * @return bool
634     *
635     * @since 1.0.0
636     */
637    public function hasAttributeValue(string $attrName, mixed $attrValue) : bool
638    {
639        foreach ($this->attributes as $attribute) {
640            if ($attribute->type->name === $attrName && $attribute->value->getValue() === $attrValue) {
641                return true;
642            }
643        }
644
645        return false;
646    }
647
648    /**
649     * Get attribute
650     *
651     * @param string $attrName Attribute name
652     *
653     * @return null|TaskAttributeValue
654     *
655     * @since 1.0.0
656     */
657    public function getAttribute(string $attrName) : ?TaskAttributeValue
658    {
659        foreach ($this->attributes as $attribute) {
660            if ($attribute->type->name === $attrName) {
661                return $attribute->value;
662            }
663        }
664
665        return null;
666    }
667
668    /**
669     * {@inheritdoc}
670     */
671    public function toArray() : array
672    {
673        return [
674            'id'             => $this->id,
675            'createdBy'      => $this->createdBy,
676            'createdAt'      => $this->createdAt,
677            'title'          => $this->title,
678            'description'    => $this->description,
679            'descriptionRaw' => $this->descriptionRaw,
680            'status'         => $this->status,
681            'type'           => $this->type,
682            'priority'       => $this->priority,
683            'due'            => $this->due,
684            'done'           => $this->done,
685            'tags'           => $this->tags,
686        ];
687    }
688
689    /**
690     * {@inheritdoc}
691     */
692    public function jsonSerialize() : mixed
693    {
694        return $this->toArray();
695    }
696}