Passed
Pull Request — master (#6257)
by
unknown
09:03
created

CStudentPublicationRepository::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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