Passed
Pull Request — master (#31)
by
unknown
14:05 queued 06:34
created

UserRepository::findOneByEmail()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 6
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 7
ccs 0
cts 7
cp 0
crap 2
rs 10
1
<?php
2
3
namespace App\Repository;
4
5
use App\Entity\ActiveDirectoryUser;
6
use App\Entity\User;
7
use App\Entity\UserType;
8
use DateTime;
9
use Doctrine\ORM\EntityManagerInterface;
10
use Doctrine\ORM\Query;
11
use Doctrine\ORM\QueryBuilder;
12
use Doctrine\ORM\Tools\Pagination\Paginator;
13
14
class UserRepository implements UserRepositoryInterface {
15
16
    private $em;
17
    private $isInTransaction = false;
18
19 14
    public function __construct(EntityManagerInterface $objectManager) {
20 14
        $this->em = $objectManager;
21 14
    }
22
23
    public function beginTransaction(): void {
24
        $this->em->beginTransaction();
25
        $this->isInTransaction = true;
26
    }
27
28
    public function commit(): void {
29
        if(!$this->isInTransaction) {
30
            return;
31
        }
32
33
        $this->em->flush();
34
        $this->em->commit();
35
        $this->isInTransaction = false;
36
    }
37
38
    public function findAll($offset = 0, $limit = null, bool $deleted = false) {
39
        $qb = $this->em
40
            ->createQueryBuilder()
41
            ->select('u')
42
            ->from(User::class, 'u')
43
            ->orderBy('u.username', 'asc')
44
            ->setFirstResult($offset);
45
46
        if($deleted === true) {
47
            $qb->where($qb->expr()->isNotNull('u.deletedAt'));
48
        } else {
49
            $qb->where($qb->expr()->isNull('u.deletedAt'));
50
        }
51
52
        if($limit !== null) {
53
            $qb->setMaxResults($limit);
54
        }
55
56
        return $qb->getQuery()->getResult();
57
    }
58
59
    public function findUsersByUsernames(array $usernames) {
60
        $qb = $this->em->createQueryBuilder();
61
62
        $qb->select(['u', 'a', 'r', 't'])
63
            ->from(User::class, 'u')
64
            ->leftJoin('u.attributes', 'a')
65
            ->leftJoin('u.userRoles', 'r')
66
            ->leftJoin('u.type', 't')
67
            ->where('u.username IN (:usernames)')
68
            ->setParameter('usernames', $usernames);
69
70
        return $qb->getQuery()->getResult();
71
    }
72
73
    public function findUsersUpdatedAfter(\DateTime $dateTime, array $usernames = [ ]) {
74
        $qb = $this->em
75
            ->createQueryBuilder();
76
77
        $qb->select(['DISTINCT u.username'])
78
            ->from(User::class, 'u')
79
            ->leftJoin('u.attributes', 'a')
80
            ->where(
81
                $qb->expr()->orX(
82
                    $qb->expr()->andX(
83
                        $qb->expr()->isNotNull('u.updatedAt'),
84
                        $qb->expr()->gt('u.updatedAt', ':datetime')
85
                    ),
86
                    $qb->expr()->andX(
87
                        $qb->expr()->isNotNull('a.updatedAt'),
88
                        $qb->expr()->gt('a.updatedAt', ':datetime')
89
                    )
90
                )
91
            )
92
            ->setParameter('datetime', $dateTime);
93
94
        if(count($usernames) > 0) {
95
            $qb->andWhere('u.username IN (:usernames)')
96
                ->setParameter('usernames', $usernames);
97
        }
98
99
        $usernames = $qb->getQuery()->getScalarResult();
100
101
        return $this->findUsersByUsernames($usernames);
102
    }
103
104 1
    public function findOneByUsername(string $username): ?User {
105 1
        $qb = $this->em->createQueryBuilder();
106
107 1
        $qb->select(['u', 'a', 'r', 't'])
108 1
            ->from(User::class, 'u')
109 1
            ->leftJoin('u.attributes', 'a')
110 1
            ->leftJoin('u.userRoles', 'r')
111 1
            ->leftJoin('u.type', 't')
112 1
            ->where('u.username = :username')
113 1
            ->setParameter('username', $username);
114
115 1
        $result = $qb->getQuery()->getResult();
116
117 1
        if(count($result) === 0) {
118
            return null;
119
        }
120
121 1
        return $result[0];
122
    }
123
124
    private function createDefaultQueryBuilder(): QueryBuilder {
125
        return $this->em
126
            ->createQueryBuilder()
127
            ->select(['u', 'a', 'r', 't'])
128
            ->from(User::class, 'u')
129
            ->leftJoin('u.attributes', 'a')
130
            ->leftJoin('u.userRoles', 'r')
131
            ->leftJoin('u.type', 't');
132
    }
133
134
    /**
135
     * @inheritDoc
136
     */
137
    public function findOneByEmail(string $email): ?User {
138
        return $this->createDefaultQueryBuilder()
139
            ->where('u.email = :email')
140
            ->setParameter('email', $email)
141
            ->setMaxResults(1)
142
            ->getQuery()
143
            ->getOneOrNullResult();
144
    }
145
146 1
    public function persist(User $user) {
147 1
        $this->em->persist($user);
148 1
        if($this->isInTransaction === false) {
149 1
            $this->em->flush();
150
        }
151 1
    }
152
153
    public function remove(User $user) {
154
        $this->em->remove($user);
155
        if($this->isInTransaction === false) {
156
            $this->em->flush();
157
        }
158
    }
159
160
    /**
161
     * @inheritDoc
162
     */
163
    public function getPaginatedUsers($itemsPerPage, &$page, $type = null, $role = null, $query = null, bool $deleted = false): Paginator {
164
        $qb = $this->em
165
            ->createQueryBuilder()
166
            ->select('u')
167
            ->from(User::class, 'u')
168
            ->orderBy('u.username', 'asc');
169
170
        $qbInner = $this->em
171
            ->createQueryBuilder()
172
            ->select('uInner.id')
173
            ->from(User::class, 'uInner')
174
            ->leftJoin('uInner.userRoles', 'rInner');
175
176
        if(!empty($query)) {
177
            $qbInner
178
                ->andWhere(
179
                    $qb->expr()->orX(
180
                        'uInner.username LIKE :query',
181
                        'uInner.firstname LIKE :query',
182
                        'uInner.lastname LIKE :query',
183
                        'uInner.email LIKE :query'
184
                    )
185
                );
186
            $qb->setParameter('query', '%' . $query . '%');
187
        }
188
189
        if($type !== null) {
190
            $qbInner
191
                ->andWhere(
192
                    'u.type = :type'
193
                );
194
            $qb->setParameter('type', $type);
195
        }
196
197
        if($role !== null) {
198
            $qbInner->andWhere(
199
                'rInner.id = :role'
200
            );
201
            $qb->setParameter('role', $role);
202
        }
203
204
        if($deleted === true) {
205
            $qbInner->andWhere($qb->expr()->isNotNull('u.deletedAt'));
206
        } else {
207
            $qbInner->andWhere($qb->expr()->isNull('u.deletedAt'));
208
        }
209
210
        if(!is_numeric($page) || $page < 1) {
211
            $page = 1;
212
        }
213
214
        $qb->where(
215
            $qb->expr()->in('u.id', $qbInner->getDQL())
216
        );
217
218
        $offset = ($page - 1) * $itemsPerPage;
219
220
        $paginator = new Paginator($qb);
221
        $paginator->getQuery()
222
            ->setMaxResults($itemsPerPage)
223
            ->setFirstResult($offset);
224
225
        return $paginator;
226
    }
227
228
229
    /**
230
     * @inheritDoc
231
     */
232
    public function findActiveDirectoryUserByObjectGuid(string $guid): ?ActiveDirectoryUser {
233
        return $this->em->getRepository(ActiveDirectoryUser::class)
234
            ->findOneBy(['objectGuid' => $guid]);
235
    }
236
237
    /**
238
     * @inheritDoc
239
     */
240
    public function findAllActiveDirectoryUsersObjectGuid(): array {
241
        return array_map(function(array $item) {
242
            return $item['objectGuid'];
243
        },
244
            $this->em->createQueryBuilder()
245
                ->select('u.objectGuid')
246
                ->from(ActiveDirectoryUser::class, 'u')
247
                ->getQuery()
248
                ->getScalarResult()
249
        );
250
    }
251
252
    /**
253
     * @inheritDoc
254
     */
255
    public function findAllUuids($offset = 0, $limit = null) {
256
        $qb = $this->em
257
            ->createQueryBuilder()
258
            ->select('u.uuid')
259
            ->from(User::class, 'u')
260
            ->orderBy('u.username', 'asc')
261
            ->setFirstResult($offset);
262
263
        if($limit !== null) {
264
            $qb->setMaxResults($limit);
265
        }
266
267
        return array_map(function(array $item) {
268
            return $item['uuid'];
269
        }, $qb->getQuery()->getScalarResult());
270
    }
271
272 5
    public function findOneByExternalId(string $externalId): ?User {
273 5
        return $this->em
274 5
            ->getRepository(User::class)
275 5
            ->findOneBy([
276 5
                'externalId' => $externalId
277
            ]);
278
    }
279
280
    public function findOneByUuid(string $uuid): ?User {
281
        return $this->em
282
            ->getRepository(User::class)
283
            ->findOneBy([
284
                'uuid' => $uuid
285
            ]);
286
    }
287
288
    /**
289
     * @inheritDoc
290
     */
291
    public function findNextNonProvisionedUsers(int $limit): array {
292
        return $this->em
293
            ->createQueryBuilder()
294
            ->select('u')
295
            ->from(User::class, 'u')
296
            ->orderBy('u.createdAt', 'asc')
297
            ->where('u.isProvisioned = false')
298
            ->setMaxResults($limit)
299
            ->getQuery()
300
            ->getResult();
301
    }
302
303
    /**
304
     * @inheritDoc
305
     */
306
    public function countUsers(?UserType $userType = null): int {
307
        $qb = $this->em->createQueryBuilder();
308
309
        $qb
310
            ->select('COUNT(u.id)')
311
            ->from(User::class, 'u')
312
            ->where($qb->expr()->isNull('u.deletedAt'));
313
314
        if($userType !== null) {
315
            $qb->andWhere('u.type = :type')
316
                ->setParameter('type', $userType);
317
        }
318
319
        return $qb->getQuery()
320
            ->getSingleScalarResult();
321
    }
322
323
    /**
324
     * @inheritDoc
325
     */
326
    public function findAllLinkedUsers(int $offset, int $limit): array {
327
        $qb = $this->createDefaultQueryBuilder()
328
            ->where('t.canLinkStudents = true');
329
330
        return $qb->getQuery()->getResult();
331
    }
332
333
    /**
334
     * @inheritDoc
335
     */
336
    public function findAllExternalIdsByExternalIdList(array $externalIds): array {
337
        if(count($externalIds) === 0) {
338
            return [];
339
        }
340
341
        $qb = $this->em->createQueryBuilder();
342
        $qb
343
            ->select('u.externalId')
344
            ->from(User::class, 'u')
345
            ->where($qb->expr()->in('u.externalId', ':ids'))
346
            ->setParameter('ids', $externalIds);
347
348
        $result = $qb->getQuery()->getResult(Query::HYDRATE_ARRAY);
349
350
        return array_map(function($row) {
351
            return $row['externalId'];
352
        }, $result);
353
    }
354
355
    /**
356
     * @inheritDoc
357
     */
358
    public function removeDeletedUsers(DateTime $threshold): int {
359
        $qb = $this->em->createQueryBuilder();
360
361
        $qb->delete(User::class, 'u')
362
            ->where($qb->expr()->isNotNull('u.deletedAt'))
363
            ->andWhere('u.deletedAt < :threshold')
364
            ->setParameter('threshold', $threshold);
365
366
        return $qb->getQuery()->execute();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $qb->getQuery()->execute() could return the type array which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
367
    }
368
}