CStudentPublication::getIid()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 4
rs 10
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CourseBundle\Entity;
8
9
use ApiPlatform\Doctrine\Common\Filter\OrderFilterInterface;
10
use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
11
use ApiPlatform\Metadata\ApiFilter;
12
use ApiPlatform\Metadata\ApiResource;
13
use ApiPlatform\Metadata\Delete;
14
use ApiPlatform\Metadata\Get;
15
use ApiPlatform\Metadata\GetCollection;
16
use ApiPlatform\Metadata\Post;
17
use ApiPlatform\Metadata\Put;
18
use Chamilo\CoreBundle\Controller\Api\CreateStudentPublicationFileAction;
19
use Chamilo\CoreBundle\Entity\AbstractResource;
20
use Chamilo\CoreBundle\Entity\ResourceInterface;
21
use Chamilo\CoreBundle\Entity\ResourceNode;
22
use Chamilo\CoreBundle\Entity\Session;
23
use Chamilo\CoreBundle\Entity\User;
24
use Chamilo\CoreBundle\Filter\CidFilter;
25
use Chamilo\CoreBundle\Filter\ParentNullFilter;
26
use Chamilo\CoreBundle\Filter\SidFilter;
27
use Chamilo\CoreBundle\State\CStudentPublicationDeleteProcessor;
28
use Chamilo\CoreBundle\State\CStudentPublicationPostStateProcessor;
29
use Chamilo\CourseBundle\Repository\CStudentPublicationRepository;
30
use DateTime;
31
use Doctrine\Common\Collections\ArrayCollection;
32
use Doctrine\Common\Collections\Collection;
33
use Doctrine\ORM\Mapping as ORM;
34
use Stringable;
35
use Symfony\Component\Serializer\Annotation\Groups;
36
use Symfony\Component\Validator\Constraints as Assert;
37
38
#[ORM\Table(name: 'c_student_publication')]
39
#[ORM\Entity(repositoryClass: CStudentPublicationRepository::class)]
40
#[ApiResource(
41
    operations: [
42
        new Put(
43
            security: "is_granted('EDIT', object.resourceNode)",
44
            processor: CStudentPublicationPostStateProcessor::class
45
        ),
46
        new Get(
47
            normalizationContext: [
48
                'groups' => ['student_publication:read', 'student_publication:item:get'],
49
            ],
50
            security: "is_granted('VIEW', object.resourceNode)",
51
        ),
52
        new GetCollection(),
53
        new Delete(
54
            security: "is_granted('DELETE', object.resourceNode)",
55
            processor: CStudentPublicationDeleteProcessor::class
56
        ),
57
        new Post(
58
            security: "is_granted('ROLE_CURRENT_COURSE_TEACHER') or is_granted('ROLE_CURRENT_COURSE_SESSION_TEACHER') or is_granted('ROLE_TEACHER')",
59
            processor: CStudentPublicationPostStateProcessor::class
60
        ),
61
        new Post(
62
            uriTemplate: '/c_student_publications/upload',
63
            controller: CreateStudentPublicationFileAction::class,
64
            security: "is_granted('ROLE_STUDENT') or is_granted('ROLE_STUDENT_BOSS')",
65
            validationContext: ['groups' => ['Default', 'c_student_publication:write']],
66
            deserialize: false
67
        ),
68
    ],
69
    normalizationContext: [
70
        'groups' => ['student_publication:read'],
71
    ],
72
    denormalizationContext: [
73
        'groups' => ['c_student_publication:write'],
74
    ],
75
    order: ['sentDate' => 'DESC'],
76
)]
77
#[ApiFilter(
78
    OrderFilter::class,
79
    properties: [
80
        'title',
81
        'sentDate' => ['nulls_comparison' => OrderFilterInterface::NULLS_SMALLEST],
82
        'assignment.expiresOn' => ['nulls_comparison' => OrderFilterInterface::NULLS_SMALLEST],
83
        'assingment.endsOn' => ['nulls_comparison' => OrderFilterInterface::NULLS_SMALLEST],
84
    ]
85
)]
86
#[ApiFilter(ParentNullFilter::class, properties: ['publicationParent.iid' => null])]
87
#[ApiFilter(filterClass: CidFilter::class)]
88
#[ApiFilter(filterClass: SidFilter::class)]
89
class CStudentPublication extends AbstractResource implements ResourceInterface, Stringable
90
{
91
    #[Groups(['c_student_publication:write', 'student_publication:read'])]
92
    public bool $addToGradebook = false;
93
94
    #[Groups(['c_student_publication:write'])]
95
    public int $gradebookCategoryId = 0;
96
97
    #[Groups(['c_student_publication:write', 'student_publication:read'])]
98
    public bool $addToCalendar = false;
99
    #[ORM\Column(name: 'iid', type: 'integer')]
100
    #[ORM\Id]
101
    #[ORM\GeneratedValue]
102
    protected ?int $iid = null;
103
104
    #[Assert\NotBlank]
105
    #[ORM\Column(name: 'title', type: 'string', length: 255, nullable: false)]
106
    #[Groups(['c_student_publication:write', 'student_publication:read'])]
107
    protected string $title;
108
109
    #[ORM\Column(name: 'description', type: 'text', nullable: true)]
110
    #[Groups(['c_student_publication:write', 'student_publication:item:get', 'student_publication:read'])]
111
    protected ?string $description;
112
113
    #[ORM\Column(name: 'author', type: 'string', length: 255, nullable: true)]
114
    protected ?string $author = null;
115
116
    #[ORM\Column(name: 'active', type: 'integer', nullable: true)]
117
    protected ?int $active = null;
118
119
    #[ORM\Column(name: 'accepted', type: 'boolean', nullable: true)]
120
    protected ?bool $accepted = null;
121
122
    #[ORM\Column(name: 'post_group_id', type: 'integer', nullable: false)]
123
    protected int $postGroupId;
124
125
    #[ORM\Column(name: 'sent_date', type: 'datetime', nullable: true)]
126
    #[Groups(['student_publication:read'])]
127
    protected ?DateTime $sentDate;
128
129
    #[Assert\NotBlank]
130
    #[Assert\Choice(callback: 'getFileTypes')]
131
    #[ORM\Column(name: 'filetype', type: 'string', length: 10, nullable: false)]
132
    protected string $filetype;
133
134
    #[ORM\Column(name: 'has_properties', type: 'integer', nullable: false)]
135
    protected int $hasProperties;
136
137
    #[ORM\Column(name: 'view_properties', type: 'boolean', nullable: true)]
138
    protected ?bool $viewProperties = null;
139
140
    #[ORM\Column(name: 'qualification', type: 'float', precision: 6, scale: 2, nullable: false)]
141
    #[Groups(['c_student_publication:write', 'student_publication:read'])]
142
    protected float $qualification;
143
144
    #[ORM\Column(name: 'date_of_qualification', type: 'datetime', nullable: true)]
145
    protected ?DateTime $dateOfQualification = null;
146
147
    /**
148
     * @var Collection<int, CStudentPublication>
149
     */
150
    #[ORM\OneToMany(mappedBy: 'publicationParent', targetEntity: self::class, cascade: ['remove'], orphanRemoval: true)]
151
    protected Collection $children;
152
153
    /**
154
     * @var Collection<int, CStudentPublicationComment>
155
     */
156
    #[ORM\OneToMany(mappedBy: 'publication', targetEntity: CStudentPublicationComment::class)]
157
    #[Groups(['student_publication:read'])]
158
    protected Collection $comments;
159
160
    #[Groups(['c_student_publication:write', 'student_publication:read', 'student_publication_comment:read'])]
161
    #[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')]
162
    #[ORM\JoinColumn(name: 'parent_id', referencedColumnName: 'iid')]
163
    protected ?CStudentPublication $publicationParent;
164
165
    #[Groups(['student_publication:read', 'student_publication_comment:read'])]
166
    #[ORM\ManyToOne(targetEntity: User::class)]
167
    #[ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
168
    protected User $user;
169
170
    #[Groups(['c_student_publication:write', 'student_publication:read'])]
171
    #[ORM\OneToOne(mappedBy: 'publication', targetEntity: CStudentPublicationAssignment::class, cascade: ['persist', 'remove'])]
172
    #[Assert\Valid]
173
    protected ?CStudentPublicationAssignment $assignment = null;
174
175
    #[ORM\Column(name: 'qualificator_id', type: 'integer', nullable: false)]
176
    protected int $qualificatorId;
177
178
    #[Assert\NotBlank]
179
    #[ORM\Column(name: 'weight', type: 'float', precision: 6, scale: 2, nullable: false)]
180
    #[Groups(['c_student_publication:write', 'student_publication:read'])]
181
    protected float $weight = 0;
182
183
    #[ORM\Column(name: 'allow_text_assignment', type: 'integer', nullable: false)]
184
    #[Groups(['c_student_publication:write', 'student_publication:item:get', 'student_publication:read'])]
185
    protected int $allowTextAssignment;
186
187
    #[Groups(['student_publication:read'])]
188
    #[ORM\Column(name: 'contains_file', type: 'integer', nullable: false)]
189
    protected int $containsFile;
190
191
    #[ORM\Column(name: 'document_id', type: 'integer', nullable: false)]
192
    protected int $documentId;
193
194
    #[ORM\Column(name: 'filesize', type: 'integer', nullable: true)]
195
    protected ?int $fileSize = null;
196
197
    #[ORM\Column(name: 'duration', type: 'integer', nullable: true)]
198
    protected ?int $duration = null;
199
200
    #[ORM\ManyToOne(targetEntity: CGroupCategory::class)]
201
    #[ORM\JoinColumn(name: 'group_category_id', referencedColumnName: 'iid', nullable: true)]
202
    protected ?CGroupCategory $groupCategory = null;
203
204
    #[ORM\Column(name: 'student_delete_own_publication', type: 'boolean', nullable: true, options: ['default' => 0])]
205
    protected ?bool $studentDeleteOwnPublication = null;
206
207
    #[ORM\Column(name: 'default_visibility', type: 'boolean', nullable: true, options: ['default' => 0])]
208
    protected ?bool $defaultVisibility = null;
209
210
    #[Groups(['c_student_publication:write', 'student_publication:read'])]
211
    #[ORM\Column(name: 'extensions', type: 'text', nullable: true)]
212
    protected ?string $extensions = null;
213
214
    #[ORM\Column(name: 'group_category_work_id', type: 'integer', nullable: false, options: ['default' => 0])]
215
    #[Groups(['c_student_publication:write', 'student_publication:read'])]
216
    protected int $groupCategoryWorkId = 0;
217
218
    public function __construct()
219
    {
220
        $this->description = '';
221
        $this->documentId = 0;
222
        $this->active = 1;
223
        $this->hasProperties = 0;
224
        $this->containsFile = 0;
225
        $this->publicationParent = null;
226
        $this->qualificatorId = 0;
227
        $this->qualification = 0;
228
        $this->assignment = null;
229
        $this->postGroupId = 0;
230
        $this->allowTextAssignment = 0;
231
        $this->filetype = 'folder';
232
        $this->sentDate = new DateTime();
233
        $this->children = new ArrayCollection();
234
        $this->comments = new ArrayCollection();
235
    }
236
237
    public function __toString(): string
238
    {
239
        return $this->getTitle();
240
    }
241
242
    public function getTitle(): string
243
    {
244
        return $this->title;
245
    }
246
247
    public function setTitle(string $title): self
248
    {
249
        $this->title = $title;
250
251
        return $this;
252
    }
253
254
    public function getFileTypes(): array
255
    {
256
        return ['file', 'folder'];
257
    }
258
259
    public function getDescription(): ?string
260
    {
261
        return $this->description;
262
    }
263
264
    public function setDescription(string $description): self
265
    {
266
        $this->description = $description;
267
268
        return $this;
269
    }
270
271
    public function getAuthor(): ?string
272
    {
273
        return $this->author;
274
    }
275
276
    public function setAuthor(string $author): self
277
    {
278
        $this->author = $author;
279
280
        return $this;
281
    }
282
283
    public function getActive(): ?int
284
    {
285
        return $this->active;
286
    }
287
288
    public function setActive(int $active): self
289
    {
290
        $this->active = $active;
291
292
        return $this;
293
    }
294
295
    public function getAccepted(): ?bool
296
    {
297
        return $this->accepted;
298
    }
299
300
    public function setAccepted(bool $accepted): self
301
    {
302
        $this->accepted = $accepted;
303
304
        return $this;
305
    }
306
307
    public function getPostGroupId(): int
308
    {
309
        return $this->postGroupId;
310
    }
311
312
    public function setPostGroupId(int $postGroupId): static
313
    {
314
        $this->postGroupId = $postGroupId;
315
316
        return $this;
317
    }
318
319
    public function getSentDate(): ?DateTime
320
    {
321
        return $this->sentDate;
322
    }
323
324
    public function setSentDate(DateTime $sentDate): self
325
    {
326
        $this->sentDate = $sentDate;
327
328
        return $this;
329
    }
330
331
    public function getFiletype(): string
332
    {
333
        return $this->filetype;
334
    }
335
336
    public function setFiletype(string $filetype): self
337
    {
338
        $this->filetype = $filetype;
339
340
        return $this;
341
    }
342
343
    public function getHasProperties(): int
344
    {
345
        return $this->hasProperties;
346
    }
347
348
    public function setHasProperties(int $hasProperties): self
349
    {
350
        $this->hasProperties = $hasProperties;
351
352
        return $this;
353
    }
354
355
    public function getViewProperties(): ?bool
356
    {
357
        return $this->viewProperties;
358
    }
359
360
    public function setViewProperties(bool $viewProperties): self
361
    {
362
        $this->viewProperties = $viewProperties;
363
364
        return $this;
365
    }
366
367
    public function getQualification(): float
368
    {
369
        return $this->qualification;
370
    }
371
372
    public function setQualification(float $qualification): self
373
    {
374
        $this->qualification = $qualification;
375
376
        return $this;
377
    }
378
379
    public function getDateOfQualification(): ?DateTime
380
    {
381
        return $this->dateOfQualification;
382
    }
383
384
    public function setDateOfQualification(DateTime $dateOfQualification): self
385
    {
386
        $this->dateOfQualification = $dateOfQualification;
387
388
        return $this;
389
    }
390
391
    public function getQualificatorId(): int
392
    {
393
        return $this->qualificatorId;
394
    }
395
396
    public function setQualificatorId(int $qualificatorId): static
397
    {
398
        $this->qualificatorId = $qualificatorId;
399
400
        return $this;
401
    }
402
403
    public function getWeight(): float
404
    {
405
        return $this->weight;
406
    }
407
408
    public function setWeight(float $weight): self
409
    {
410
        $this->weight = $weight;
411
412
        return $this;
413
    }
414
415
    public function getAllowTextAssignment(): int
416
    {
417
        return $this->allowTextAssignment;
418
    }
419
420
    public function setAllowTextAssignment(int $allowTextAssignment): self
421
    {
422
        $this->allowTextAssignment = $allowTextAssignment;
423
424
        return $this;
425
    }
426
427
    public function getContainsFile(): int
428
    {
429
        return $this->containsFile;
430
    }
431
432
    public function setContainsFile(int $containsFile): self
433
    {
434
        $this->containsFile = $containsFile;
435
436
        return $this;
437
    }
438
439
    public function getDocumentId(): int
440
    {
441
        return $this->documentId;
442
    }
443
444
    public function setDocumentId(int $documentId): self
445
    {
446
        $this->documentId = $documentId;
447
448
        return $this;
449
    }
450
451
    public function getFileSize(): int
452
    {
453
        return $this->fileSize;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->fileSize could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
454
    }
455
456
    public function setFileSize(int $fileSize): self
457
    {
458
        $this->fileSize = $fileSize;
459
460
        return $this;
461
    }
462
463
    #[Groups(['student_publication:read'])]
464
    public function getCorrection(): ?ResourceNode
465
    {
466
        if (!$this->hasResourceNode()) {
467
            return null;
468
        }
469
470
        $children = $this->getResourceNode()->getChildren();
471
472
        foreach ($children as $child) {
473
            $resourceType = $child->getResourceType();
474
            if (!$resourceType) {
475
                continue;
476
            }
477
478
            $name = $resourceType->getTitle();
479
480
            if ('student_publications_corrections' === $name) {
481
                return $child;
482
            }
483
        }
484
485
        return null;
486
    }
487
488
    #[Groups(['student_publication:read'])]
489
    public function getCorrectionTitle(): ?string
490
    {
491
        return $this->getExtensions();
492
    }
493
494
    #[Groups(['student_publication:read'])]
495
    public function getChildFileCount(): int
496
    {
497
        return $this->children
498
            ->filter(fn (self $child) => 'file' === $child->getFiletype() && 2 !== $child->getActive())
499
            ->count()
500
        ;
501
    }
502
503
    /**
504
     * @return Collection<int, CStudentPublication>
505
     */
506
    public function getChildren(): Collection
507
    {
508
        return $this->children;
509
    }
510
511
    public function setChildren(Collection $children): self
512
    {
513
        $this->children = $children;
514
515
        return $this;
516
    }
517
518
    public function getAssignment(): ?CStudentPublicationAssignment
519
    {
520
        return $this->assignment;
521
    }
522
523
    public function setAssignment(?CStudentPublicationAssignment $assignment): self
524
    {
525
        $this->assignment = $assignment;
526
527
        if ($assignment) {
528
            $assignment->setPublication($this);
529
        }
530
531
        return $this;
532
    }
533
534
    public function getPublicationParent(): ?self
535
    {
536
        return $this->publicationParent;
537
    }
538
539
    public function setPublicationParent(?self $publicationParent): self
540
    {
541
        $this->publicationParent = $publicationParent;
542
543
        return $this;
544
    }
545
546
    public function getUser(): User
547
    {
548
        return $this->user;
549
    }
550
551
    public function setUser(User $user): self
552
    {
553
        $this->user = $user;
554
555
        return $this;
556
    }
557
558
    /**
559
     * @return Collection<int, CStudentPublicationComment>
560
     */
561
    public function getComments(): Collection
562
    {
563
        return $this->comments;
564
    }
565
566
    public function setComments(Collection $comments): self
567
    {
568
        $this->comments = $comments;
569
570
        return $this;
571
    }
572
573
    public function getDuration(): ?int
574
    {
575
        return $this->duration;
576
    }
577
578
    public function setDuration(?int $duration): self
579
    {
580
        $this->duration = $duration;
581
582
        return $this;
583
    }
584
585
    public function getGroupCategory(): ?CGroupCategory
586
    {
587
        return $this->groupCategory;
588
    }
589
590
    public function setGroupCategory(?CGroupCategory $groupCategory): self
591
    {
592
        $this->groupCategory = $groupCategory;
593
594
        return $this;
595
    }
596
597
    public function getStudentDeleteOwnPublication(): ?bool
598
    {
599
        return $this->studentDeleteOwnPublication;
600
    }
601
602
    public function setStudentDeleteOwnPublication(?bool $studentDeleteOwnPublication): self
603
    {
604
        $this->studentDeleteOwnPublication = $studentDeleteOwnPublication;
605
606
        return $this;
607
    }
608
609
    public function getDefaultVisibility(): ?bool
610
    {
611
        return $this->defaultVisibility;
612
    }
613
614
    public function setDefaultVisibility(?bool $defaultVisibility): self
615
    {
616
        $this->defaultVisibility = $defaultVisibility;
617
618
        return $this;
619
    }
620
621
    public function getExtensions(): ?string
622
    {
623
        return $this->extensions;
624
    }
625
626
    public function setExtensions(?string $extensions): self
627
    {
628
        $this->extensions = $extensions;
629
630
        return $this;
631
    }
632
633
    public function getResourceIdentifier(): int
634
    {
635
        return $this->getIid();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getIid() could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
636
    }
637
638
    #[Groups(['student_publication:read'])]
639
    public function getIid(): ?int
640
    {
641
        return $this->iid;
642
    }
643
644
    public function getResourceName(): string
645
    {
646
        return $this->getTitle();
647
    }
648
649
    public function setResourceName(string $name): self
650
    {
651
        return $this->setTitle($name);
652
    }
653
654
    #[Groups(['student_publication:read'])]
655
    public function getUniqueStudentAttemptsTotal(): int
656
    {
657
        $userIdList = [];
658
659
        $reduce = $this->children
660
            ->filter(function (self $child) {
661
                return $child->postGroupId === $this->postGroupId;
662
            })
663
            ->reduce(function (int $accumulator, self $child) use (&$userIdList): int {
664
                $user = $child->getUser();
665
666
                if (!\in_array($user->getId(), $userIdList, true)) {
667
                    $userIdList[] = $user->getId();
668
669
                    return $accumulator + 1;
670
                }
671
672
                return $accumulator;
673
            }, 0)
674
        ;
675
676
        return $reduce ?: 0;
677
    }
678
679
    #[Groups(['student_publication:read'])]
680
    public function getStudentSubscribedToWork(): int
681
    {
682
        $firstLink = $this->getFirstResourceLink();
683
684
        $course = $firstLink->getCourse();
685
        $session = $firstLink->getSession();
686
        $group = $firstLink->getGroup();
687
688
        if ($group) {
689
            return $group->getMembers()->count();
690
        }
691
692
        if ($session) {
693
            return $session->getSessionRelCourseRelUsersByStatus($course, Session::STUDENT)->count();
694
        }
695
696
        if ($course) {
697
            return $course->getStudentSubscriptions()->count();
698
        }
699
700
        return 0;
701
    }
702
703
    #[Groups(['student_publication:read'])]
704
    public function getCorrectionDownloadUrl(): ?string
705
    {
706
        $correctionNode = $this->getCorrection();
707
        if ($correctionNode && $correctionNode->getFirstResourceFile()) {
708
            $uuid = $correctionNode->getUuid();
709
            if ($uuid) {
710
                return '/r/student_publication/student_publications_corrections/'.$uuid.'/download';
711
            }
712
        }
713
714
        return null;
715
    }
716
717
    public function getGroupCategoryWorkId(): int
718
    {
719
        return $this->groupCategoryWorkId;
720
    }
721
722
    public function setGroupCategoryWorkId(int $groupCategoryWorkId): self
723
    {
724
        $this->groupCategoryWorkId = $groupCategoryWorkId;
725
726
        return $this;
727
    }
728
}
729