Passed
Push — master ( f7c169...528c62 )
by Angel Fernando Quiroz
08:03 queued 15s
created

SessionRepository::getUpcomingSessionsByUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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