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) { |
|
|
|
|
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
|
|
|
|
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.