Passed
Push — master ( b5ae77...224836 )
by Angel Fernando Quiroz
10:45 queued 14s
created

getCurrentSessionsWithDatesForUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 38
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 26
nc 1
nop 2
dl 0
loc 38
rs 9.504
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\CoreBundle\Repository;
8
9
use Chamilo\CoreBundle\Entity\AccessUrl;
10
use Chamilo\CoreBundle\Entity\Course;
11
use Chamilo\CoreBundle\Entity\Session;
12
use Chamilo\CoreBundle\Entity\SessionRelCourse;
13
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
14
use Chamilo\CoreBundle\Entity\SessionRelUser;
15
use Chamilo\CoreBundle\Entity\User;
16
use DateTime;
17
use DateTimeZone;
18
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
19
use Doctrine\ORM\Query\Expr\Join;
20
use Doctrine\ORM\QueryBuilder;
21
use Doctrine\Persistence\ManagerRegistry;
22
use Exception;
23
24
/**
25
 * @author Julio Montoya <[email protected]>
26
 */
27
class SessionRepository extends ServiceEntityRepository
28
{
29
    public function __construct(ManagerRegistry $registry)
30
    {
31
        parent::__construct($registry, Session::class);
32
    }
33
34
    public function create(): ?Session
35
    {
36
        return new Session();
37
    }
38
39
    public function update(Session $session): void
40
    {
41
        $this->getEntityManager()->persist($session);
42
        $this->getEntityManager()->flush();
43
    }
44
45
    /**
46
     * @return array<SessionRelUser>
47
     */
48
    public function getUsersByAccessUrl(Session $session, AccessUrl $url, array $relationTypeList = []): array
49
    {
50
        if (0 === $session->getUsers()->count()) {
51
            return [];
52
        }
53
54
        $qb = $this->addSessionRelUserFilterByUrl($session, $url);
55
        $qb->orderBy('sru.relationType');
56
57
        if ($relationTypeList) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $relationTypeList of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
58
            $qb->andWhere(
59
                $qb->expr()->in('sru.relationType', $relationTypeList)
60
            );
61
        }
62
63
        return $qb->getQuery()->getResult();
64
    }
65
66
    public function getSessionsByUser(User $user, AccessUrl $url): QueryBuilder
67
    {
68
        $qb = $this->createQueryBuilder('s');
69
        $qb
70
            ->innerJoin('s.users', 'sru')
71
            ->leftJoin('s.urls', 'urls')
72
            ->where($qb->expr()->eq('sru.user', ':user'))
73
            ->andWhere($qb->expr()->eq('urls.url', ':url'))
74
            ->setParameters([
75
                'user' => $user,
76
                'url' => $url,
77
            ])
78
        ;
79
80
        return $qb;
81
    }
82
83
    /**
84
     * @return array<int, Session>
85
     *
86
     * @throws Exception
87
     */
88
    public function getPastSessionsWithDatesForUser(User $user, AccessUrl $url): array
89
    {
90
        $now = new DateTime('now', new DateTimeZone('UTC'));
91
92
        $qb = $this->getSessionsByUser($user, $url);
93
        $qb
94
            ->andWhere(
95
                $qb->expr()->andX(
96
                    $qb->expr()->isNotNull('s.accessEndDate'),
97
                    $qb->expr()->lt('s.accessEndDate', ':now')
98
                )
99
            )
100
            ->setParameter('now', $now)
101
        ;
102
103
        return $qb->getQuery()->getResult();
104
    }
105
106
    /**
107
     * @return array<int, Session>
108
     *
109
     * @throws Exception
110
     */
111
    public function getCurrentSessionsWithDatesForUser(User $user, AccessUrl $url): array
112
    {
113
        $now = new DateTime('now', new DateTimeZone('UTC'));
114
115
        $qb = $this->getSessionsByUser($user, $url);
116
        $qb
117
            ->andWhere(
118
                $qb->expr()->orX(
119
                    $qb->expr()->andX(
120
                        $qb->expr()->isNull('s.accessStartDate'),
121
                        $qb->expr()->isNull('s.accessEndDate'),
122
                        $qb->expr()->orX(
123
                            $qb->expr()->eq('s.duration', 0),
124
                            $qb->expr()->isNull('s.duration')
125
                        )
126
                    ),
127
                    $qb->expr()->andX(
128
                        $qb->expr()->isNotNull('s.accessStartDate'),
129
                        $qb->expr()->isNull('s.accessEndDate'),
130
                        $qb->expr()->lte('s.accessStartDate', ':now')
131
                    ),
132
                    $qb->expr()->andX(
133
                        $qb->expr()->isNotNull('s.accessStartDate'),
134
                        $qb->expr()->isNotNull('s.accessEndDate'),
135
                        $qb->expr()->lte('s.accessStartDate', ':now'),
136
                        $qb->expr()->gte('s.accessEndDate', ':now')
137
                    ),
138
                    $qb->expr()->andX(
139
                        $qb->expr()->isNull('s.accessStartDate'),
140
                        $qb->expr()->isNotNull('s.accessEndDate'),
141
                        $qb->expr()->gte('s.accessEndDate', ':now')
142
                    )
143
                )
144
            )
145
            ->setParameter('now', $now)
146
        ;
147
148
        return $qb->getQuery()->getResult();
149
    }
150
151
    /**
152
     * @return array<int, Session>
153
     *
154
     * @throws Exception
155
     */
156
    public function getUpcomingSessionsWithDatesForUser(User $user, AccessUrl $url): array
157
    {
158
        $now = new DateTime('now', new DateTimeZone('UTC'));
159
160
        $qb = $this->getSessionsByUser($user, $url);
161
        $qb
162
            ->andWhere(
163
                $qb->expr()->andX(
164
                    $qb->expr()->isNotNull('s.accessStartDate'),
165
                    $qb->expr()->gt('s.accessStartDate', ':now')
166
                )
167
            )
168
            ->setParameter('now', $now)
169
        ;
170
171
        return $qb->getQuery()->getResult();
172
    }
173
174
    public function addUserInCourse(int $relationType, User $user, Course $course, Session $session): void
175
    {
176
        if (!$user->isActive()) {
177
            throw new Exception('User not active');
178
        }
179
180
        if (!$session->hasCourse($course)) {
181
            $msg = sprintf('Course %s is not subscribed to the session %s', $course->getTitle(), $session->getTitle());
182
183
            throw new Exception($msg);
184
        }
185
186
        if (!\in_array($relationType, Session::getRelationTypeList(), true)) {
187
            throw new Exception(sprintf('Cannot handle relationType %s', $relationType));
188
        }
189
190
        switch ($relationType) {
191
            case Session::DRH:
192
                if ($user->hasRole('ROLE_RRHH')) {
193
                    $session->addUserInSession(Session::DRH, $user);
194
                }
195
196
                break;
197
198
            case Session::STUDENT:
199
                $session
200
                    ->addUserInSession(Session::STUDENT, $user)
201
                    ->addUserInCourse(Session::STUDENT, $user, $course)
202
                ;
203
204
                break;
205
206
            case Session::COURSE_COACH:
207
                if ($user->hasRole('ROLE_TEACHER')) {
208
                    $session
209
                        ->addUserInSession(Session::COURSE_COACH, $user)
210
                        ->addUserInCourse(
211
                            Session::COURSE_COACH,
212
                            $user,
213
                            $course
214
                        )
215
                    ;
216
                }
217
218
                break;
219
        }
220
    }
221
222
    /**
223
     * @return array<SessionRelCourse>
224
     */
225
    public function getSessionCoursesByStatusInUserSubscription(User $user, Session $session, int $relationType, ?AccessUrl $url = null): array
226
    {
227
        $qb = $this->getEntityManager()->createQueryBuilder();
228
229
        $qb->select('src')
230
            ->from(SessionRelCourse::class, 'src')
231
            ->innerJoin(
232
                SessionRelUser::class,
233
                'sru',
234
                Join::WITH,
235
                'src.session = sru.session'
236
            )
237
            ->innerJoin('src.session', 'session')
238
            ->where(
239
                $qb->expr()->eq('session', ':session')
240
            )
241
            ->andWhere(
242
                $qb->expr()->eq('sru.user', ':user')
243
            )
244
            ->andWhere(
245
                $qb->expr()->eq('sru.relationType', ':relation_type')
246
            )
247
        ;
248
249
        $parameters = [
250
            'session' => $session,
251
            'user' => $user,
252
            'relation_type' => $relationType,
253
        ];
254
255
        if ($url) {
256
            $qb->innerJoin('session.urls', 'urls')
257
                ->andWhere(
258
                    $qb->expr()->eq('urls.url', ':url')
259
                )
260
            ;
261
262
            $parameters['url'] = $url;
263
        }
264
265
        $qb->setParameters($parameters);
266
267
        return $qb->getQuery()->getResult();
268
    }
269
270
    /**
271
     * @return array<SessionRelCourse>
272
     */
273
    public function getSessionCoursesByStatusInCourseSubscription(User $user, Session $session, int $status, ?AccessUrl $url = null): array
274
    {
275
        $qb = $this->getEntityManager()->createQueryBuilder();
276
277
        $qb->select('src')
278
            ->from(SessionRelCourse::class, 'src')
279
            ->innerJoin(
280
                SessionRelCourseRelUser::class,
281
                'srcru',
282
                Join::WITH,
283
                'src.session = srcru.session AND src.course = srcru.course'
284
            )
285
            ->innerJoin('srcru.session', 'session')
286
            ->where(
287
                $qb->expr()->eq('session', ':session')
288
            )
289
            ->andWhere(
290
                $qb->expr()->eq('srcru.user', ':user')
291
            )
292
            ->andWhere(
293
                $qb->expr()->eq('srcru.status', ':status')
294
            )
295
        ;
296
297
        $parameters = [
298
            'session' => $session,
299
            'user' => $user,
300
            'status' => $status,
301
        ];
302
303
        if ($url) {
304
            $qb->innerJoin('session.urls', 'urls')
305
                ->andWhere(
306
                    $qb->expr()->eq('urls.url', ':url')
307
                )
308
            ;
309
310
            $parameters['url'] = $url;
311
        }
312
313
        $qb->setParameters($parameters);
314
315
        return $qb->getQuery()->getResult();
316
    }
317
318
    private function addSessionRelUserFilterByUrl(Session $session, AccessUrl $url): QueryBuilder
319
    {
320
        $qb = $this->getEntityManager()->createQueryBuilder();
321
        $qb
322
            ->select('sru')
323
            ->from(SessionRelUser::class, 'sru')
324
            ->innerJoin('sru.user', 'u')
325
            ->innerJoin('u.portals', 'p')
326
            ->andWhere('sru.session = :session AND p.url = :url')
327
            ->setParameters([
328
                'session' => $session,
329
                'url' => $url,
330
            ])
331
        ;
332
333
        return $qb;
334
    }
335
336
    public function getUserFollowedSessionsInAccessUrl(User $user, AccessUrl $url): QueryBuilder
337
    {
338
        $callback = fn (Session $session) => $session->getId();
339
340
        if ($user->isHRM()) {
341
            $idList = array_map($callback, $user->getDRHSessions());
342
        } elseif ($user->isTeacher() || COURSEMANAGER === $user->getStatus()) {
343
            $idListAsCoach = $user
344
                ->getSessionsByStatusInCourseSubscription(Session::COURSE_COACH)
345
                ->map($callback)
346
                ->getValues()
347
            ;
348
            $idListAsGeneralCoach = array_map($callback, $user->getSessionsAsGeneralCoach());
349
            $idList = array_merge($idListAsCoach, $idListAsGeneralCoach);
350
        } elseif ($user->isSessionAdmin()) {
351
            $idList = array_map($callback, $user->getSessionsAsAdmin());
352
        } else {
353
            $idList = array_map($callback, $user->getSessionsAsStudent());
354
        }
355
356
        $qb = $this->createQueryBuilder('s');
357
        $qb
358
            ->innerJoin('s.urls', 'u')
359
            ->where($qb->expr()->eq('u.url', $url->getId()))
360
            ->andWhere($qb->expr()->in('s.id', ':id_list'))
361
            ->setParameter('id_list', $idList)
362
        ;
363
364
        return $qb;
365
    }
366
}
367