Passed
Push — master ( b61354...af9f4d )
by Julito
19:31
created

UserRepository::getSessionAdmins()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 18
nc 1
nop 1
dl 0
loc 26
rs 9.6666
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\AccessUrl;
10
use Chamilo\CoreBundle\Entity\Course;
11
use Chamilo\CoreBundle\Entity\Message;
12
use Chamilo\CoreBundle\Entity\ResourceNode;
13
use Chamilo\CoreBundle\Entity\Session;
14
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
15
use Chamilo\CoreBundle\Entity\TrackELogin;
16
use Chamilo\CoreBundle\Entity\TrackEOnline;
17
use Chamilo\CoreBundle\Entity\User;
18
use Chamilo\CoreBundle\Repository\ResourceRepository;
19
use Chamilo\CourseBundle\Entity\CSurveyInvitation;
20
use Datetime;
21
use Doctrine\Common\Collections\Collection;
22
use Doctrine\Common\Collections\Criteria;
23
use Doctrine\DBAL\Types\Types;
24
use Doctrine\ORM\Query\Expr\Join;
25
use Doctrine\ORM\QueryBuilder;
26
use Doctrine\Persistence\ManagerRegistry;
27
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
28
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
29
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
30
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
31
32
class UserRepository extends ResourceRepository implements PasswordUpgraderInterface
33
{
34
    protected ?UserPasswordHasherInterface $hasher = null;
35
36
    public function __construct(ManagerRegistry $registry)
37
    {
38
        parent::__construct($registry, User::class);
39
    }
40
41
    public function loadUserByIdentifier(string $identifier): ?User
42
    {
43
        return $this->findOneBy([
44
            'username' => $identifier,
45
        ]);
46
    }
47
48
    public function setHasher(UserPasswordHasherInterface $hasher): void
49
    {
50
        $this->hasher = $hasher;
51
    }
52
53
    public function createUser(): User
54
    {
55
        return new User();
56
    }
57
58
    public function updateUser(User $user, bool $andFlush = true): void
59
    {
60
        $this->updateCanonicalFields($user);
61
        $this->updatePassword($user);
62
        $this->getEntityManager()->persist($user);
63
        if ($andFlush) {
64
            $this->getEntityManager()->flush();
65
        }
66
    }
67
68
    public function canonicalize(string $string): string
69
    {
70
        $encoding = mb_detect_encoding($string, mb_detect_order(), true);
71
72
        return $encoding
73
            ? mb_convert_case($string, MB_CASE_LOWER, $encoding)
74
            : mb_convert_case($string, MB_CASE_LOWER);
75
    }
76
77
    public function updateCanonicalFields(User $user): void
78
    {
79
        $user->setUsernameCanonical($this->canonicalize($user->getUsername()));
80
        $user->setEmailCanonical($this->canonicalize($user->getEmail()));
81
    }
82
83
    public function updatePassword(User $user): void
84
    {
85
        $password = (string) $user->getPlainPassword();
86
        if ('' !== $password) {
87
            $password = $this->hasher->hashPassword($user, $password);
0 ignored issues
show
Bug introduced by
The method hashPassword() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

87
            /** @scrutinizer ignore-call */ 
88
            $password = $this->hasher->hashPassword($user, $password);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
88
            $user->setPassword($password);
89
            $user->eraseCredentials();
90
        }
91
    }
92
93
    public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void
94
    {
95
        /** @var User $user */
96
        $user->setPassword($newHashedPassword);
97
        $this->getEntityManager()->persist($user);
98
        $this->getEntityManager()->flush();
99
    }
100
101
    public function getRootUser(): User
102
    {
103
        $qb = $this->createQueryBuilder('u');
104
        $qb
105
            ->innerJoin(
106
                'u.resourceNode',
107
                'r'
108
            )
109
        ;
110
        $qb
111
            ->where('r.creator = u')
112
            ->andWhere('r.parent IS NULL')
113
            ->getFirstResult()
114
        ;
115
116
        $rootUser = $qb->getQuery()->getSingleResult();
117
118
        if (null === $rootUser) {
119
            throw new UserNotFoundException('Root user not found');
120
        }
121
122
        return $rootUser;
123
    }
124
125
    public function deleteUser(User $user): void
126
    {
127
        $em = $this->getEntityManager();
128
        $type = $user->getResourceNode()->getResourceType();
129
        $rootUser = $this->getRootUser();
130
131
        // User children will be set to the root user.
132
        $criteria = Criteria::create()->where(Criteria::expr()->eq('resourceType', $type));
133
        $userNodeCreatedList = $user->getResourceNodes()->matching($criteria);
134
        /** @var ResourceNode $userCreated */
135
        foreach ($userNodeCreatedList as $userCreated) {
136
            $userCreated->setCreator($rootUser);
137
        }
138
139
        $em->remove($user->getResourceNode());
140
141
        foreach ($user->getGroups() as $group) {
142
            $user->removeGroup($group);
143
        }
144
145
        $em->remove($user);
146
        $em->flush();
147
    }
148
149
    public function addUserToResourceNode(int $userId, int $creatorId): ResourceNode
150
    {
151
        /** @var User $user */
152
        $user = $this->find($userId);
153
        $creator = $this->find($creatorId);
154
155
        $resourceNode = new ResourceNode();
156
        $resourceNode
157
            ->setTitle($user->getUsername())
158
            ->setCreator($creator)
159
            ->setResourceType($this->getResourceType())
160
            //->setParent($resourceNode)
161
        ;
162
163
        $user->setResourceNode($resourceNode);
164
165
        $this->getEntityManager()->persist($resourceNode);
166
        $this->getEntityManager()->persist($user);
167
168
        return $resourceNode;
169
    }
170
171
    public function addRoleListQueryBuilder(array $roleList, QueryBuilder $qb = null): QueryBuilder
172
    {
173
        $qb = $this->getOrCreateQueryBuilder($qb, 'u');
174
        if (!empty($roleList)) {
175
            $qb
176
                ->andWhere('u.roles IN (:roles)')
177
                ->setParameter('roles', $roleList, Types::ARRAY)
178
            ;
179
        }
180
181
        return $qb;
182
    }
183
184
    public function findByUsername(string $username): ?User
185
    {
186
        $user = $this->findOneBy([
187
            'username' => $username,
188
        ]);
189
190
        if (null === $user) {
191
            throw new UserNotFoundException(sprintf("User with id '%s' not found.", $username));
192
        }
193
194
        return $user;
195
    }
196
197
    /**
198
     * Get a filtered list of user by role and (optionally) access url.
199
     *
200
     * @param string $keyword     The query to filter
201
     * @param int    $accessUrlId The access URL ID
202
     *
203
     * @return User[]
204
     */
205
    public function findByRole(string $role, string $keyword, int $accessUrlId = 0)
206
    {
207
        $qb = $this->createQueryBuilder('u');
208
209
        $this->addAccessUrlQueryBuilder($accessUrlId, $qb);
210
        $this->addRoleQueryBuilder($role, $qb);
211
        $this->addSearchByKeywordQueryBuilder($keyword, $qb);
212
213
        return $qb->getQuery()->getResult();
214
    }
215
216
    /**
217
     * Get course user relationship based in the course_rel_user table.
218
     *
219
     * @return Course[]
220
     */
221
    public function getCourses(User $user, AccessUrl $url, int $status, string $keyword = '')
222
    {
223
        $qb = $this->createQueryBuilder('u');
224
225
        $qb
226
            //->select('DISTINCT course')
227
            ->innerJoin('u.courses', 'courseRelUser')
228
            ->innerJoin('courseRelUser.course', 'course')
229
            ->innerJoin('course.urls', 'accessUrlRelCourse')
230
            ->innerJoin('accessUrlRelCourse.url', 'url')
231
            ->where('url = :url')
232
            ->andWhere('courseRelUser.user = :user')
233
            ->andWhere('courseRelUser.status = :status')
234
            ->setParameters(
235
                [
236
                    'user' => $user,
237
                    'url' => $url,
238
                    'status' => $status,
239
                ]
240
            )
241
        //    ->addSelect('courseRelUser')
242
        ;
243
244
        if (!empty($keyword)) {
245
            $qb
246
                ->andWhere('course.title like = :keyword OR course.code like = :keyword')
247
                ->setParameter('keyword', $keyword)
248
            ;
249
        }
250
251
        $qb->orderBy('course.title', Criteria::DESC);
252
253
        $query = $qb->getQuery();
254
255
        return $query->getResult();
256
    }
257
258
    /*
259
    public function getTeachers()
260
    {
261
        $queryBuilder = $this->repository->createQueryBuilder('u');
262
263
        // Selecting course info.
264
        $queryBuilder
265
            ->select('u')
266
            ->where('u.groups.id = :groupId')
267
            ->setParameter('groupId', 1);
268
269
        $query = $queryBuilder->getQuery();
270
271
        return $query->execute();
272
    }*/
273
274
    /*public function getUsers($group)
275
    {
276
        $queryBuilder = $this->repository->createQueryBuilder('u');
277
278
        // Selecting course info.
279
        $queryBuilder
280
            ->select('u')
281
            ->where('u.groups = :groupId')
282
            ->setParameter('groupId', $group);
283
284
        $query = $queryBuilder->getQuery();
285
286
        return $query->execute();
287
    }*/
288
289
    /**
290
     * Get the coaches for a course within a session.
291
     *
292
     * @param Session $session The session
293
     * @param Course  $course  The course
294
     */
295
    public function getCoachesForSessionCourse(Session $session, Course $course): Collection
296
    {
297
        $qb = $this->createQueryBuilder('u');
298
299
        $qb->select('u')
300
            ->innerJoin(
301
                'ChamiloCoreBundle:SessionRelCourseRelUser',
302
                'scu',
303
                Join::WITH,
304
                'scu.user = u'
305
            )
306
            ->where(
307
                $qb->expr()->andX(
308
                    $qb->expr()->eq('scu.session', $session->getId()),
309
                    $qb->expr()->eq('scu.course', $course->getId()),
310
                    $qb->expr()->eq('scu.status', SessionRelCourseRelUser::STATUS_COURSE_COACH)
311
                )
312
            )
313
        ;
314
315
        return $qb->getQuery()->getResult();
316
    }
317
318
    /**
319
     * Get course user relationship based in the course_rel_user table.
320
     *
321
     * @return array
322
     */
323
    /*public function getCourses(User $user)
324
    {
325
        $qb = $this->createQueryBuilder('user');
326
327
        // Selecting course info.
328
        $qb->select('c');
329
330
        // Loading User.
331
        //$qb->from('Chamilo\CoreBundle\Entity\User', 'u');
332
333
        // Selecting course
334
        $qb->innerJoin('Chamilo\CoreBundle\Entity\Course', 'c');
335
336
        //@todo check app settings
337
        //$qb->add('orderBy', 'u.lastname ASC');
338
339
        $wherePart = $qb->expr()->andx();
340
341
        // Get only users subscribed to this course
342
        $wherePart->add($qb->expr()->eq('user.userId', $user->getUserId()));
343
344
        $qb->where($wherePart);
345
        $query = $qb->getQuery();
346
347
        return $query->execute();
348
    }
349
350
    public function getTeachers()
351
    {
352
        $qb = $this->createQueryBuilder('u');
353
354
        // Selecting course info.
355
        $qb
356
            ->select('u')
357
            ->where('u.groups.id = :groupId')
358
            ->setParameter('groupId', 1);
359
360
        $query = $qb->getQuery();
361
362
        return $query->execute();
363
    }*/
364
365
    /*public function getUsers($group)
366
    {
367
        $qb = $this->createQueryBuilder('u');
368
369
        // Selecting course info.
370
        $qb
371
            ->select('u')
372
            ->where('u.groups = :groupId')
373
            ->setParameter('groupId', $group);
374
375
        $query = $qb->getQuery();
376
377
        return $query->execute();
378
    }*/
379
380
    /**
381
     * Get the sessions admins for a user.
382
     *
383
     * @return array
384
     */
385
    public function getSessionAdmins(User $user)
386
    {
387
        $qb = $this->createQueryBuilder('u');
388
        $qb
389
            ->distinct()
390
            ->innerJoin(
391
                'ChamiloCoreBundle:SessionRelUser',
392
                'su',
393
                Join::WITH,
394
                'u = su.user'
395
            )
396
            ->innerJoin(
397
                'ChamiloCoreBundle:SessionRelCourseRelUser',
398
                'scu',
399
                Join::WITH,
400
                'su.session = scu.session'
401
            )
402
            ->where(
403
                $qb->expr()->eq('scu.user', $user->getId())
404
            )
405
            ->andWhere(
406
                $qb->expr()->eq('su.relationType', SESSION_RELATION_TYPE_RRHH)
407
            )
408
        ;
409
410
        return $qb->getQuery()->getResult();
411
    }
412
413
    /**
414
     * Get the student bosses for a user.
415
     *
416
     * @return array
417
     */
418
    public function getStudentBosses(User $user)
419
    {
420
        $qb = $this->createQueryBuilder('u');
421
        $qb
422
            ->distinct()
423
            ->innerJoin(
424
                'ChamiloCoreBundle:UserRelUser',
425
                'uu',
426
                Join::WITH,
427
                'u.id = uu.friendUserId'
428
            )
429
            ->where(
430
                $qb->expr()->eq('uu.relationType', USER_RELATION_TYPE_BOSS)
431
            )
432
            ->andWhere(
433
                $qb->expr()->eq('uu.userId', $user->getId())
434
            )
435
        ;
436
437
        return $qb->getQuery()->getResult();
438
    }
439
440
    /**
441
     * Get number of users in URL.
442
     *
443
     * @return int
444
     */
445
    public function getCountUsersByUrl(AccessUrl $url)
446
    {
447
        return $this->createQueryBuilder('u')
448
            ->select('COUNT(a)')
449
            ->innerJoin('a.portals', 'p')
450
            ->where('p.portal = :p')
451
            ->setParameters([
452
                'p' => $url,
453
            ])
454
            ->getQuery()
455
            ->getSingleScalarResult()
456
        ;
457
    }
458
459
    /**
460
     * Get number of users in URL.
461
     *
462
     * @return int
463
     */
464
    public function getCountTeachersByUrl(AccessUrl $url)
465
    {
466
        $qb = $this->createQueryBuilder('u');
467
468
        return $qb
469
            ->select('COUNT(u)')
470
            ->innerJoin('a.portals', 'p')
471
            ->where('p.portal = :p')
472
            ->andWhere($qb->expr()->in('u.roles', ['ROLE_TEACHER']))
473
            ->setParameters([
474
                'p' => $url,
475
            ])
476
            ->getQuery()
477
            ->getSingleScalarResult()
478
        ;
479
    }
480
481
    /**
482
     * Find potential users to send a message.
483
     *
484
     * @todo remove  api_is_platform_admin
485
     *
486
     * @param int    $currentUserId The current user ID
487
     * @param string $searchFilter  Optional. The search text to filter the user list
488
     * @param int    $limit         Optional. Sets the maximum number of results to retrieve
489
     *
490
     * @return User[]
491
     */
492
    public function findUsersToSendMessage(int $currentUserId, string $searchFilter = null, int $limit = 10)
493
    {
494
        $allowSendMessageToAllUsers = api_get_setting('allow_send_message_to_all_platform_users');
495
        $accessUrlId = api_get_multiple_access_url() ? api_get_current_access_url_id() : 1;
496
497
        $messageTool = 'true' === api_get_setting('allow_message_tool');
498
        if (!$messageTool) {
499
            return [];
500
        }
501
502
        $qb = $this->createQueryBuilder('u');
503
        $this->addActiveAndNotAnonUserQueryBuilder($qb);
504
        $this->addAccessUrlQueryBuilder($accessUrlId, $qb);
505
506
        $dql = null;
507
        if ('true' === api_get_setting('allow_social_tool')) {
508
            // All users
509
            if ('true' === $allowSendMessageToAllUsers || api_is_platform_admin()) {
510
                $this->addNotCurrentUserQueryBuilder($currentUserId, $qb);
511
            /*$dql = "SELECT DISTINCT U
512
                    FROM ChamiloCoreBundle:User U
513
                    LEFT JOIN ChamiloCoreBundle:AccessUrlRelUser R
514
                    WITH U = R.user
515
                    WHERE
516
                        U.active = 1 AND
517
                        U.status != 6  AND
518
                        U.id != {$currentUserId} AND
519
                        R.url = {$accessUrlId}";*/
520
            } else {
521
                $this->addOnlyMyFriendsQueryBuilder($currentUserId, $qb);
522
                /*$dql = 'SELECT DISTINCT U
523
                        FROM ChamiloCoreBundle:AccessUrlRelUser R, ChamiloCoreBundle:UserRelUser UF
524
                        INNER JOIN ChamiloCoreBundle:User AS U
525
                        WITH UF.friendUserId = U
526
                        WHERE
527
                            U.active = 1 AND
528
                            U.status != 6 AND
529
                            UF.relationType NOT IN('.USER_RELATION_TYPE_DELETED.', '.USER_RELATION_TYPE_RRHH.") AND
530
                            UF.user = {$currentUserId} AND
531
                            UF.friendUserId != {$currentUserId} AND
532
                            U = R.user AND
533
                            R.url = {$accessUrlId}";*/
534
            }
535
        } else {
536
            if ('true' === $allowSendMessageToAllUsers) {
537
                $this->addNotCurrentUserQueryBuilder($currentUserId, $qb);
538
            } else {
539
                return [];
540
            }
541
542
            /*else {
543
                $time_limit = (int) api_get_setting('time_limit_whosonline');
544
                $online_time = time() - ($time_limit * 60);
545
                $limit_date = api_get_utc_datetime($online_time);
546
                $dql = "SELECT DISTINCT U
547
                        FROM ChamiloCoreBundle:User U
548
                        INNER JOIN ChamiloCoreBundle:TrackEOnline T
549
                        WITH U.id = T.loginUserId
550
                        WHERE
551
                          U.active = 1 AND
552
                          T.loginDate >= '".$limit_date."'";
553
            }*/
554
        }
555
556
        if (!empty($searchFilter)) {
557
            $this->addSearchByKeywordQueryBuilder($searchFilter, $qb);
558
        }
559
560
        return $qb->getQuery()->getResult();
561
    }
562
563
    /**
564
     * Get the list of HRM who have assigned this user.
565
     *
566
     * @return User[]
567
     */
568
    public function getAssignedHrmUserList(int $userId, int $urlId)
569
    {
570
        $qb = $this->createQueryBuilder('u');
571
        $this->addAccessUrlQueryBuilder($urlId, $qb);
572
        $this->addActiveAndNotAnonUserQueryBuilder($qb);
573
        $this->addUserRelUserQueryBuilder($userId, USER_RELATION_TYPE_RRHH, $qb);
574
575
        return $qb->getQuery()->getResult();
576
    }
577
578
    /**
579
     * Get the last login from the track_e_login table.
580
     * This might be different from user.last_login in the case of legacy users
581
     * as user.last_login was only implemented in 1.10 version with a default
582
     * value of NULL (not the last record from track_e_login).
583
     *
584
     * @return null|TrackELogin
585
     */
586
    public function getLastLogin(User $user)
587
    {
588
        $qb = $this->createQueryBuilder('u');
589
590
        return $qb
591
            ->select('l')
592
            ->innerJoin('u.logins', 'l')
593
            ->where(
594
                $qb->expr()->eq('l.user', $user)
595
            )
596
            ->setMaxResults(1)
597
            ->orderBy('u.loginDate', Criteria::DESC)
598
            ->getQuery()
599
            ->getOneOrNullResult()
600
        ;
601
    }
602
603
    public function addAccessUrlQueryBuilder(int $accessUrlId, QueryBuilder $qb = null): QueryBuilder
604
    {
605
        $qb = $this->getOrCreateQueryBuilder($qb, 'u');
606
        $qb
607
            ->innerJoin('u.portals', 'p')
608
            ->andWhere('p.url = :url')
609
            ->setParameter('url', $accessUrlId, Types::INTEGER)
610
        ;
611
612
        return $qb;
613
    }
614
615
    public function addActiveAndNotAnonUserQueryBuilder(QueryBuilder $qb = null): QueryBuilder
616
    {
617
        $qb = $this->getOrCreateQueryBuilder($qb, 'u');
618
        $qb
619
            ->andWhere('u.active = 1')
620
            ->andWhere('u.status <> :status')
621
            ->setParameter('status', User::ANONYMOUS, Types::INTEGER)
622
        ;
623
624
        return $qb;
625
    }
626
627
    public function addExpirationDateQueryBuilder(QueryBuilder $qb = null): QueryBuilder
628
    {
629
        $qb = $this->getOrCreateQueryBuilder($qb, 'u');
630
        $qb
631
            ->andWhere('u.registrationDate IS NULL OR u.registrationDate > :now')
632
            ->setParameter('now', new Datetime(), Types::DATETIME_MUTABLE)
633
        ;
634
635
        return $qb;
636
    }
637
638
    /**
639
     * @return CSurveyInvitation[]
640
     */
641
    public function getUserPendingInvitations(User $user)
642
    {
643
        $qb = $this->createQueryBuilder('u');
644
        $qb
645
            ->select('s')
646
            ->innerJoin('u.surveyInvitations', 's')
647
            ->andWhere('s.user = :u')
648
            ->andWhere('s.availFrom <= :now AND s.availTill >= :now')
649
            ->andWhere('s.answered = 0')
650
            ->setParameters([
651
                'now' => new Datetime(),
652
                'u' => $user,
653
            ])
654
            ->orderBy('s.availTill', Criteria::ASC)
655
        ;
656
657
        return $qb->getQuery()->getResult();
658
    }
659
660
    private function addRoleQueryBuilder(string $role, QueryBuilder $qb = null): QueryBuilder
661
    {
662
        $qb = $this->getOrCreateQueryBuilder($qb, 'u');
663
        $qb
664
            ->andWhere('u.roles LIKE :roles')
665
            ->setParameter('roles', '%"'.$role.'"%', Types::STRING)
666
        ;
667
668
        return $qb;
669
    }
670
671
    private function addSearchByKeywordQueryBuilder($keyword, QueryBuilder $qb = null): QueryBuilder
672
    {
673
        $qb = $this->getOrCreateQueryBuilder($qb, 'u');
674
        $qb
675
            ->andWhere('
676
                u.firstname LIKE :keyword OR
677
                u.lastname LIKE :keyword OR
678
                u.email LIKE :keyword OR
679
                u.username LIKE :keyword
680
            ')
681
            ->setParameter('keyword', "%$keyword%", Types::STRING)
682
            ->orderBy('u.firstname', Criteria::ASC)
683
        ;
684
685
        return $qb;
686
    }
687
688
    private function addUserRelUserQueryBuilder(int $userId, int $relationType, QueryBuilder $qb = null): QueryBuilder
689
    {
690
        $qb = $this->getOrCreateQueryBuilder($qb, 'u');
691
        $qb->leftJoin('u.userRelUsers', 'relations');
692
        $qb
693
            ->andWhere('relations.relationType = :relationType')
694
            ->andWhere('relations.user = :userRelation AND relations.friend <> :userRelation')
695
            ->setParameter('relationType', $relationType)
696
            ->setParameter('userRelation', $userId)
697
        ;
698
699
        return $qb;
700
    }
701
702
    private function addOnlyMyFriendsQueryBuilder(int $userId, QueryBuilder $qb = null): QueryBuilder
703
    {
704
        $qb = $this->getOrCreateQueryBuilder($qb, 'u');
705
        $qb
706
            ->leftJoin('u.userRelUsers', 'relations')
707
            ->andWhere(
708
                $qb->expr()->notIn('relations.relationType', [USER_RELATION_TYPE_DELETED, USER_RELATION_TYPE_RRHH])
709
            )
710
            ->andWhere('relations.user = :user AND relations.friend <> :user')
711
            ->setParameter('user', $userId, Types::INTEGER)
712
        ;
713
714
        return $qb;
715
    }
716
717
    private function addNotCurrentUserQueryBuilder(int $userId, QueryBuilder $qb = null): QueryBuilder
718
    {
719
        $qb = $this->getOrCreateQueryBuilder($qb, 'u');
720
        $qb
721
            ->andWhere('u.id <> :id')
722
            ->setParameter('id', $userId, Types::INTEGER)
723
        ;
724
725
        return $qb;
726
    }
727
}
728