Passed
Pull Request — master (#5678)
by Angel Fernando Quiroz
07:55
created

UsergroupRepository::getInvitedUsersByGroup()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 1
dl 0
loc 13
rs 9.9666
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\Node;
8
9
use Chamilo\CoreBundle\Entity\User;
10
use Chamilo\CoreBundle\Entity\Usergroup;
11
use Chamilo\CoreBundle\Entity\UsergroupRelUser;
12
use Chamilo\CoreBundle\Repository\ResourceRepository;
13
use Chamilo\CoreBundle\ServiceHelper\AccessUrlHelper;
14
use Doctrine\Persistence\ManagerRegistry;
15
use Exception;
16
17
class UsergroupRepository extends ResourceRepository
18
{
19
    public function __construct(
20
        ManagerRegistry $registry,
21
        private readonly IllustrationRepository $illustrationRepository,
22
        private readonly AccessUrlHelper $accessUrlHelper,
23
    ) {
24
        parent::__construct($registry, Usergroup::class);
25
    }
26
27
    /**
28
     * @param int|array $relationType
29
     */
30
    public function getGroupsByUser(int $userId, int $relationType = 0, bool $withImage = false): array
31
    {
32
        $qb = $this->createQueryBuilder('g')
33
            ->innerJoin('g.users', 'gu')
34
            ->where('gu.user = :userId')
35
            ->setParameter('userId', $userId)
36
            ->andWhere('g.groupType = :socialClass')
37
            ->setParameter('socialClass', Usergroup::SOCIAL_CLASS)
38
        ;
39
40
        if (0 !== $relationType) {
41
            if (\is_array($relationType)) {
42
                $qb->andWhere('gu.relationType IN (:relationType)')
43
                    ->setParameter('relationType', $relationType)
44
                ;
45
            } else {
46
                $qb->andWhere('gu.relationType = :relationType')
47
                    ->setParameter('relationType', $relationType)
48
                ;
49
            }
50
        }
51
52
        $qb->innerJoin('g.urls', 'u')
53
            ->andWhere('u.accessUrl = :urlId')
54
            ->setParameter('urlId', $this->accessUrlHelper->getCurrent()->getId())
55
        ;
56
57
        $qb->orderBy('g.createdAt', 'DESC');
58
        $query = $qb->getQuery();
59
60
        return $query->getResult();
61
    }
62
63
    public function countMembers(int $usergroupId): int
64
    {
65
        $qb = $this->createQueryBuilder('g')
66
            ->select('count(gu.id)')
67
            ->innerJoin('g.users', 'gu')
68
            ->where('g.id = :usergroupId')
69
            ->setParameter('usergroupId', $usergroupId)
70
        ;
71
72
        return (int) $qb->getQuery()->getSingleScalarResult();
73
    }
74
75
    public function getNewestGroups(int $limit = 30, string $query = ''): array
76
    {
77
        $qb = $this->createQueryBuilder('g')
78
            ->select('g, COUNT(gu) AS HIDDEN memberCount')
79
            ->innerJoin('g.users', 'gu')
80
            ->innerJoin('g.urls', 'u')
81
            ->where('g.groupType = :socialClass')
82
            ->andWhere('u.accessUrl = :urlId')
83
            ->setParameter('socialClass', Usergroup::SOCIAL_CLASS)
84
            ->setParameter('urlId', $this->accessUrlHelper->getCurrent()->getId())
85
            ->groupBy('g')
86
            ->orderBy('g.createdAt', 'DESC')
87
            ->setMaxResults($limit)
88
        ;
89
90
        if (!empty($query)) {
91
            $qb->andWhere('g.title LIKE :query OR g.description LIKE :query')
92
                ->setParameter('query', '%'.$query.'%')
93
            ;
94
        }
95
96
        return $qb->getQuery()->getResult();
97
    }
98
99
    public function getPopularGroups(int $limit = 30): array
100
    {
101
        $qb = $this->createQueryBuilder('g')
102
            ->select('g, COUNT(gu) as HIDDEN memberCount')
103
            ->innerJoin('g.users', 'gu')
104
            ->innerJoin('g.urls', 'u')
105
            ->where('g.groupType = :socialClass')
106
            ->andWhere('u.accessUrl = :urlId')
107
            ->setParameter('socialClass', Usergroup::SOCIAL_CLASS)
108
            ->andWhere('gu.relationType IN (:relationTypes)')
109
            ->setParameter('relationTypes', [
110
                Usergroup::GROUP_USER_PERMISSION_ADMIN,
111
                Usergroup::GROUP_USER_PERMISSION_READER,
112
                Usergroup::GROUP_USER_PERMISSION_HRM,
113
            ])
114
            ->setParameter('urlId', $this->accessUrlHelper->getCurrent()->getId())
115
            ->groupBy('g')
116
            ->orderBy('memberCount', 'DESC')
117
            ->setMaxResults($limit)
118
        ;
119
120
        return $qb->getQuery()->getResult();
121
    }
122
123
    public function findGroupById($id)
124
    {
125
        return $this->createQueryBuilder('ug')
126
            ->where('ug.id = :id')
127
            ->setParameter('id', $id)
128
            ->getQuery()
129
            ->getOneOrNullResult()
130
        ;
131
    }
132
133
    public function searchGroups(string $searchTerm): array
134
    {
135
        $queryBuilder = $this->createQueryBuilder('g');
136
        $queryBuilder->where('g.title LIKE :searchTerm')
137
            ->setParameter('searchTerm', '%'.$searchTerm.'%')
138
        ;
139
140
        return $queryBuilder->getQuery()->getResult();
141
    }
142
143
    public function getUsersByGroup(int $groupID)
144
    {
145
        $qb = $this->createQueryBuilder('g')
146
            ->innerJoin('g.users', 'gu')
147
            ->innerJoin('gu.user', 'u')
148
            ->where('g.id = :groupID')
149
            ->setParameter('groupID', $groupID)
150
            ->andWhere('gu.relationType IN (:relationTypes)')
151
            ->setParameter('relationTypes', [
152
                Usergroup::GROUP_USER_PERMISSION_ADMIN,
153
                Usergroup::GROUP_USER_PERMISSION_READER,
154
                Usergroup::GROUP_USER_PERMISSION_PENDING_INVITATION,
155
            ])
156
            ->select('u.id, u.username, u.email, gu.relationType, u.pictureUri')
157
        ;
158
159
        $results = $qb->getQuery()->getResult();
160
161
        $userRepository = $this->_em->getRepository(User::class);
162
163
        foreach ($results as &$user) {
164
            $user['pictureUri'] = $userRepository->getUserPicture($user['id']);
165
        }
166
167
        return $results;
168
    }
169
170
    public function addUserToGroup(int $userId, int $groupId, int $relationType = Usergroup::GROUP_USER_PERMISSION_READER): void
171
    {
172
        $group = $this->find($groupId);
173
        $user = $this->_em->getRepository(User::class)->find($userId);
174
175
        if (!$group || !$user) {
176
            throw new Exception('Group or User not found');
177
        }
178
179
        if (Usergroup::GROUP_PERMISSION_CLOSED === (int) $group->getVisibility()) {
180
            $relationType = Usergroup::GROUP_USER_PERMISSION_PENDING_INVITATION;
181
        }
182
183
        $existingRelation = $this->_em->getRepository(UsergroupRelUser::class)->findOneBy([
184
            'usergroup' => $group,
185
            'user' => $user,
186
        ]);
187
188
        if (!$existingRelation) {
189
            $existingRelation = new UsergroupRelUser();
190
            $existingRelation->setUsergroup($group);
191
            $existingRelation->setUser($user);
192
        }
193
194
        $existingRelation->setRelationType($relationType);
195
196
        $this->_em->persist($existingRelation);
197
        $this->_em->flush();
198
    }
199
200
    public function updateUserRole($userId, $groupId, $relationType = Usergroup::GROUP_USER_PERMISSION_READER): void
201
    {
202
        $qb = $this->createQueryBuilder('g');
203
        $qb->delete(UsergroupRelUser::class, 'gu')
204
            ->where('gu.usergroup = :groupId')
205
            ->andWhere('gu.user = :userId')
206
            ->setParameter('groupId', $groupId)
207
            ->setParameter('userId', $userId)
208
        ;
209
210
        $query = $qb->getQuery();
211
        $query->execute();
212
213
        $group = $this->find($groupId);
214
        $user = $this->_em->getRepository(User::class)->find($userId);
215
216
        if (!$group || !$user) {
217
            throw new Exception('Group or User not found');
218
        }
219
220
        $usergroupRelUser = new UsergroupRelUser();
221
        $usergroupRelUser->setUsergroup($group);
222
        $usergroupRelUser->setUser($user);
223
        $usergroupRelUser->setRelationType($relationType);
224
225
        $this->_em->persist($usergroupRelUser);
226
        $this->_em->flush();
227
    }
228
229
    public function removeUserFromGroup(int $userId, int $groupId, bool $checkLeaveRestriction = true): bool
230
    {
231
        /** @var Usergroup $group */
232
        $group = $this->find($groupId);
233
        $user = $this->_em->getRepository(User::class)->find($userId);
234
235
        if (!$group || !$user) {
0 ignored issues
show
introduced by
$group is of type Chamilo\CoreBundle\Entity\Usergroup, thus it always evaluated to true.
Loading history...
236
            throw new Exception('Group or User not found');
237
        }
238
239
        if ($checkLeaveRestriction && !$group->getAllowMembersToLeaveGroup()) {
240
            throw new Exception('Members are not allowed to leave this group');
241
        }
242
243
        $relation = $this->_em->getRepository(UsergroupRelUser::class)->findOneBy([
244
            'usergroup' => $group,
245
            'user' => $user,
246
        ]);
247
248
        if ($relation) {
249
            $this->_em->remove($relation);
250
            $this->_em->flush();
251
252
            return true;
253
        }
254
255
        return false;
256
    }
257
258
    public function getInvitedUsersByGroup(int $groupID)
259
    {
260
        $qb = $this->createQueryBuilder('g')
261
            ->innerJoin('g.users', 'gu')
262
            ->innerJoin('gu.user', 'u')
263
            ->where('g.id = :groupID')
264
            ->setParameter('groupID', $groupID)
265
            ->andWhere('gu.relationType = :relationType')
266
            ->setParameter('relationType', Usergroup::GROUP_USER_PERMISSION_PENDING_INVITATION)
267
            ->select('u.id, u.username, u.email, gu.relationType')
268
        ;
269
270
        return $qb->getQuery()->getResult();
271
    }
272
273
    public function getInvitedUsers(int $groupId): array
274
    {
275
        $qb = $this->createQueryBuilder('g')
276
            ->innerJoin('g.users', 'rel')
277
            ->innerJoin('rel.user', 'u')
278
            ->where('g.id = :groupId')
279
            ->andWhere('rel.relationType = :relationType')
280
            ->setParameter('groupId', $groupId)
281
            ->setParameter('relationType', Usergroup::GROUP_USER_PERMISSION_PENDING_INVITATION)
282
            ->select('u')
283
        ;
284
285
        return $qb->getQuery()->getResult();
286
    }
287
288
    public function searchGroupsByTags(string $tag, int $from = 0, int $number_of_items = 10, bool $getCount = false)
289
    {
290
        $qb = $this->createQueryBuilder('g');
291
292
        if ($getCount) {
293
            $qb->select('COUNT(g.id)');
294
        } else {
295
            $qb->select('g.id, g.title, g.description, g.url, g.picture');
296
        }
297
298
        $qb
299
            ->innerJoin('g.accessUrls', 'a', 'WITH', 'g.id = a.usergroup')
300
            ->where(
301
                $qb->expr()->orX(
302
                    $qb->expr()->like('g.title', ':tag'),
303
                    $qb->expr()->like('g.description', ':tag'),
304
                    $qb->expr()->like('g.url', ':tag')
305
                )
306
            )
307
            ->andWhere('a.accessUrl = :urlId')
308
            ->setParameter('urlId', $this->accessUrlHelper->getCurrent()->getId())
309
            ->setParameter('tag', '%'.$tag.'%')
310
        ;
311
312
        if (!$getCount) {
313
            $qb->orderBy('g.title', 'ASC')
314
                ->setFirstResult($from)
315
                ->setMaxResults($number_of_items)
316
            ;
317
        }
318
319
        return $getCount ? $qb->getQuery()->getSingleScalarResult() : $qb->getQuery()->getResult();
320
    }
321
322
    public function getUsergroupPicture($userGroupId): string
323
    {
324
        $usergroup = $this->find($userGroupId);
325
        if (!$usergroup) {
326
            return '/img/icons/64/group_na.png';
327
        }
328
329
        $url = $this->illustrationRepository->getIllustrationUrl($usergroup);
330
        $params['w'] = 64;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$params was never initialized. Although not strictly required by PHP, it is generally a good practice to add $params = array(); before regardless.
Loading history...
331
        $params['rand'] = uniqid('u_', true);
332
        $paramsToString = '?'.http_build_query($params);
333
334
        return $url.$paramsToString;
335
    }
336
337
    public function isGroupMember(int $groupId, User $user): bool
338
    {
339
        if ($user->isSuperAdmin()) {
340
            return true;
341
        }
342
343
        $userRole = $this->getUserGroupRole($groupId, $user->getId());
344
345
        $allowedRoles = [
346
            Usergroup::GROUP_USER_PERMISSION_ADMIN,
347
            Usergroup::GROUP_USER_PERMISSION_MODERATOR,
348
            Usergroup::GROUP_USER_PERMISSION_READER,
349
            Usergroup::GROUP_USER_PERMISSION_HRM,
350
        ];
351
352
        return \in_array($userRole, $allowedRoles, true);
353
    }
354
355
    public function getUserGroupRole(int $groupId, int $userId): ?int
356
    {
357
        $qb = $this->createQueryBuilder('g');
358
        $qb->innerJoin('g.users', 'gu')
359
            ->where('g.id = :groupId AND gu.user = :userId')
360
            ->setParameter('groupId', $groupId)
361
            ->setParameter('userId', $userId)
362
            ->orderBy('gu.id', 'DESC')
363
            ->select('gu.relationType')
364
            ->setMaxResults(1)
365
        ;
366
367
        $result = $qb->getQuery()->getOneOrNullResult();
368
369
        return $result ? $result['relationType'] : null;
370
    }
371
372
    public function isGroupModerator(int $groupId, int $userId): bool
373
    {
374
        $relationType = $this->getUserGroupRole($groupId, $userId);
375
376
        return \in_array($relationType, [
377
            Usergroup::GROUP_USER_PERMISSION_ADMIN,
378
            Usergroup::GROUP_USER_PERMISSION_MODERATOR,
379
        ]);
380
    }
381
382
    /**
383
     * Determines whether to use the multi-URL feature.
384
     *
385
     * @return bool true if multi-URLs should be used, false otherwise
386
     */
387
    public function getUseMultipleUrl(): bool
388
    {
389
        // TODO: Implement the actual logic to determine if multi-URLs should be used.
390
        // For now, returning false as a default value.
391
        return false;
392
    }
393
394
    /**
395
     * Gets the current access URL ID.
396
     *
397
     * @return int the ID of the current access URL
398
     */
399
    public function getCurrentAccessUrlId(): int
400
    {
401
        // TODO: Implement the actual logic to obtain the current access URL ID.
402
        // For now, returning 1 as a default value.
403
        return 1;
404
    }
405
}
406