Passed
Pull Request — master (#6257)
by
unknown
08:47
created

findVisibleAssignmentsForStudent()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 26
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 21
nc 2
nop 2
dl 0
loc 26
rs 9.584
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CourseBundle\Repository;
8
9
use Chamilo\CoreBundle\Entity\Course;
10
use Chamilo\CoreBundle\Entity\CourseRelUser;
11
use Chamilo\CoreBundle\Entity\ResourceLink;
12
use Chamilo\CoreBundle\Entity\Session;
13
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
14
use Chamilo\CoreBundle\Entity\User;
15
use Chamilo\CoreBundle\Repository\ResourceRepository;
16
use Chamilo\CourseBundle\Entity\CGroup;
17
use Chamilo\CourseBundle\Entity\CStudentPublication;
18
use Doctrine\Common\Collections\Criteria;
19
use Doctrine\ORM\QueryBuilder;
20
use Doctrine\ORM\Tools\Pagination\Paginator;
21
use Doctrine\Persistence\ManagerRegistry;
22
23
final class CStudentPublicationRepository extends ResourceRepository
24
{
25
    public function __construct(ManagerRegistry $registry)
26
    {
27
        parent::__construct($registry, CStudentPublication::class);
28
    }
29
30
    public function findAllByCourse(
31
        Course $course,
32
        ?Session $session = null,
33
        ?string $title = null,
34
        ?int $active = null,
35
        ?string $fileType = null
36
    ): QueryBuilder {
37
        $qb = $this->getResourcesByCourse($course, $session);
38
39
        $this->addTitleQueryBuilder($title, $qb);
40
        $this->addActiveQueryBuilder($active, $qb);
41
        $this->addFileTypeQueryBuilder($fileType, $qb);
42
43
        return $qb;
44
    }
45
46
    public function getStudentAssignments(
47
        CStudentPublication $publication,
48
        Course $course,
49
        ?Session $session = null,
50
        ?CGroup $group = null,
51
        ?User $user = null
52
    ): QueryBuilder {
53
        $qb = $this->getResourcesByCourse($course, $session, $group);
54
55
        $this->addNotDeletedPublicationQueryBuilder($qb);
56
        $qb
57
            ->andWhere('resource.publicationParent =:publicationParent')
58
            ->setParameter('publicationParent', $publication)
59
        ;
60
61
        return $qb;
62
    }
63
64
    public function getStudentPublicationByUser(User $user, Course $course, ?Session $session = null): array
65
    {
66
        $qb = $this->findAllByCourse($course, $session);
67
68
        /** @var CStudentPublication[] $works */
69
        $works = $qb->getQuery()->getResult();
70
        $list = [];
71
        foreach ($works as $work) {
72
            $qb = $this->getStudentAssignments($work, $course, $session, null, $user);
73
            $results = $qb->getQuery()->getResult();
74
            $list[$work->getIid()]['work'] = $work;
75
            $list[$work->getIid()]['results'] = $results;
76
        }
77
78
        return $list;
79
    }
80
81
    public function countUserPublications(
82
        User $user,
83
        Course $course,
84
        ?Session $session = null,
85
        ?CGroup $group = null
86
    ): int {
87
        $qb = $this->getResourcesByCourseLinkedToUser($user, $course, $session);
88
        $qb->andWhere('resource.publicationParent IS NOT NULL');
89
90
        return $this->getCount($qb);
91
    }
92
93
    public function countCoursePublications(Course $course, ?Session $session = null, ?CGroup $group = null): int
94
    {
95
        $qb = $this->getResourcesByCourse($course, $session, $group);
96
97
        $this->addNotDeletedPublicationQueryBuilder($qb);
98
99
        return $this->getCount($qb);
100
    }
101
102
    /**
103
     * Find all the works registered by a teacher.
104
     */
105
    public function findWorksByTeacher(User $user, Course $course, ?Session $session = null): array
106
    {
107
        $qb = $this->getResourcesByCourseLinkedToUser($user, $course, $session);
108
        $qb->andWhere('resource.publicationParent IS NOT NULL');
109
110
        return $qb
111
            ->orderBy('resource.sentDate', Criteria::ASC)
112
            ->getQuery()
113
            ->getResult()
114
        ;
115
    }
116
117
    private function addActiveQueryBuilder(?int $active = null, ?QueryBuilder $qb = null): void
118
    {
119
        $qb = $this->getOrCreateQueryBuilder($qb);
120
121
        if (null !== $active) {
122
            $qb
123
                ->andWhere('resource.active = :active')
124
                ->setParameter('active', $active)
125
            ;
126
        }
127
    }
128
129
    private function addNotDeletedPublicationQueryBuilder(?QueryBuilder $qb = null): void
130
    {
131
        $qb = $this->getOrCreateQueryBuilder($qb);
132
        $qb
133
            ->andWhere('resource.active <> 2')
134
        ;
135
    }
136
137
    private function addFileTypeQueryBuilder(?string $fileType, ?QueryBuilder $qb = null): void
138
    {
139
        $qb = $this->getOrCreateQueryBuilder($qb);
140
        if (null === $fileType) {
141
            return;
142
        }
143
144
        $qb
145
            ->andWhere('resource.filetype = :filetype')
146
            ->setParameter('filetype', $fileType)
147
        ;
148
    }
149
150
    public function findVisibleAssignmentsForStudent(Course $course, ?Session $session = null): array
151
    {
152
        $qb = $this->createQueryBuilder('resource')
153
            ->select('resource', 'COUNT(comment.iid) AS commentsCount', 'MAX(child.sentDate) AS lastUpload')
154
            ->leftJoin('resource.comments', 'comment')
155
            ->leftJoin('resource.children', 'child')
156
            ->join('resource.resourceNode', 'rn')
157
            ->join('rn.resourceLinks', 'rl')
158
            ->where('resource.publicationParent IS NULL')
159
            ->andWhere('resource.active IN (0, 1)')
160
            ->andWhere('resource.filetype = :filetype')
161
            ->setParameter('filetype', 'folder')
162
            ->andWhere('rl.visibility = 2')
163
            ->andWhere('rl.course = :course')
164
            ->setParameter('course', $course)
165
            ->groupBy('resource.iid')
166
            ->orderBy('resource.sentDate', 'DESC');
167
168
        if ($session) {
169
            $qb->andWhere('rl.session = :session')
170
                ->setParameter('session', $session);
171
        } else {
172
            $qb->andWhere('rl.session IS NULL');
173
        }
174
175
        return $qb->getQuery()->getResult();
176
    }
177
178
    public function findStudentProgressByCourse(Course $course, ?Session $session): array
179
    {
180
        $em = $this->getEntityManager();
181
182
        $qb = $em->createQueryBuilder();
183
        $qb->select('sp')
184
            ->from(CStudentPublication::class, 'sp')
185
            ->join('sp.resourceNode', 'rn')
186
            ->join(ResourceLink::class, 'rl', 'WITH', 'rl.resourceNode = rn')
187
            ->where('rl.course = :course')
188
            ->andWhere($session ? 'rl.session = :session' : 'rl.session IS NULL')
189
            ->andWhere('sp.active IN (0, 1)')
190
            ->andWhere('sp.filetype = :filetype')
191
            ->andWhere('sp.publicationParent IS NULL')
192
            ->setParameter('course', $course)
193
            ->setParameter('filetype', 'folder');
194
195
        if ($session) {
196
            $qb->setParameter('session', $session);
197
        }
198
199
        $workFolders = $qb->getQuery()->getResult();
200
201
        if (empty($workFolders)) {
202
            return [];
203
        }
204
205
        $workIds = array_map(fn (CStudentPublication $sp) => $sp->getIid(), $workFolders);
206
207
        if ($session) {
208
            $students = $em->getRepository(SessionRelCourseRelUser::class)->findBy([
209
                'session' => $session,
210
                'course' => $course,
211
                'status' => Session::STUDENT,
212
            ]);
213
        } else {
214
            $students = $em->getRepository(CourseRelUser::class)->findBy([
215
                'course' => $course,
216
                'status' => CourseRelUser::STUDENT,
217
            ]);
218
        }
219
220
        if (empty($students)) {
221
            return [];
222
        }
223
224
        $studentProgress = [];
225
226
        foreach ($students as $studentRel) {
227
            $user = $studentRel->getUser();
228
229
            $qb = $em->createQueryBuilder();
230
            $qb->select('COUNT(DISTINCT sp.publicationParent)')
231
                ->from(CStudentPublication::class, 'sp')
232
                ->where('sp.user = :user')
233
                ->andWhere('sp.publicationParent IN (:workIds)')
234
                ->andWhere('sp.active IN (0, 1)')
235
                ->setParameter('user', $user)
236
                ->setParameter('workIds', $workIds);
237
238
            $submissionCount = (int) $qb->getQuery()->getSingleScalarResult();
239
240
            $studentProgress[] = [
241
                'id' => $user->getId(),
242
                'firstname' => $user->getFirstname(),
243
                'lastname' => $user->getLastname(),
244
                'submissions' => $submissionCount,
245
                'totalAssignments' => count($workIds),
246
            ];
247
        }
248
249
        return $studentProgress;
250
    }
251
252
    public function findAssignmentSubmissionsPaginated(
253
        int $assignmentId,
254
        User $user,
255
        int $page,
256
        int $itemsPerPage,
257
        array $order = []
258
    ): array {
259
        $qb = $this->createQueryBuilder('submission')
260
            ->leftJoin('submission.resourceNode', 'resourceNode')
261
            ->join('resourceNode.resourceLinks', 'resourceLink')
262
            ->where('submission.publicationParent = :assignmentId')
263
            ->andWhere('submission.filetype = :filetype')
264
            ->andWhere('resourceLink.visibility = :publishedVisibility')
265
            ->setParameter('assignmentId', $assignmentId)
266
            ->setParameter('filetype', 'file')
267
            ->setParameter('publishedVisibility', 2);
268
269
        foreach ($order as $field => $direction) {
270
            $qb->addOrderBy('submission.' . $field, $direction);
271
        }
272
273
        $qb->setFirstResult(($page - 1) * $itemsPerPage)
274
            ->setMaxResults($itemsPerPage);
275
276
        $paginator = new Paginator($qb);
277
278
        return [
279
            iterator_to_array($paginator),
280
            count($paginator),
281
        ];
282
    }
283
284
    public function findAllSubmissionsByAssignment(
285
        int $assignmentId,
286
        int $page,
287
        int $itemsPerPage,
288
        array $order = []
289
    ): array {
290
        $qb = $this->createQueryBuilder('submission')
291
            ->leftJoin('submission.user', 'user')
292
            ->addSelect('user')
293
            ->where('submission.publicationParent = :assignmentId')
294
            ->andWhere('submission.filetype = :filetype')
295
            ->setParameter('assignmentId', $assignmentId)
296
            ->setParameter('filetype', 'file');
297
298
        foreach ($order as $field => $direction) {
299
            $qb->addOrderBy('submission.' . $field, $direction);
300
        }
301
302
        $qb->setFirstResult(($page - 1) * $itemsPerPage)
303
            ->setMaxResults($itemsPerPage);
304
305
        $paginator = new Paginator($qb);
306
307
        return [
308
            iterator_to_array($paginator),
309
            count($paginator),
310
        ];
311
    }
312
}
313