Failed Conditions
Push — master ( 3cf6df...56f0b0 )
by Adrien
07:17
created

UserRepository   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Test Coverage

Coverage 98.57%

Importance

Changes 0
Metric Value
eloc 63
c 0
b 0
f 0
dl 0
loc 156
ccs 69
cts 70
cp 0.9857
rs 10
wmc 18

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getAccessibleSubQuery() 0 7 2
A getAllToQueueBalanceMessage() 0 28 2
A getOneById() 0 7 1
A getOneByLogin() 0 7 1
B getOneByLoginPassword() 0 31 9
A getAllAdministratorsToNotify() 0 14 1
A getAllNonFamilyOwnersWithAccount() 0 8 1
A getAllFamilyOwners() 0 7 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Repository;
6
7
use Application\DBAL\Types\BookingTypeType;
8
use Application\Model\User;
9
use Doctrine\DBAL\Connection;
10
use Ecodev\Felix\Repository\LimitedAccessSubQuery;
11
12
class UserRepository extends AbstractRepository implements LimitedAccessSubQuery
13
{
14
    /**
15
     * Returns pure SQL to get ID of all objects that are accessible to given user.
16
     */
17 32
    public function getAccessibleSubQuery(?\Ecodev\Felix\Model\User $user): string
18
    {
19 32
        if (!$user) {
20 3
            return '-1';
21
        }
22
23 29
        return $this->getAllIdsQuery();
24
    }
25
26
    /**
27
     * Returns the user authenticated by its email and password
28
     */
29 2
    public function getOneByLoginPassword(string $login, string $password): ?User
30
    {
31
        /** @var null|User $user */
32 2
        $user = $this->getOneByLogin($login);
33
34 2
        if (!$user) {
35 1
            return null;
36
        }
37
38
        // Check user status
39 2
        if (!in_array($user->getStatus(), [User::STATUS_ACTIVE, User::STATUS_INACTIVE, User::STATUS_NEW], true)) {
40
            return null;
41
        }
42
43 2
        $hashFromDb = $user->getPassword();
44 2
        $isMd5 = mb_strlen($hashFromDb) === 32 && ctype_xdigit($hashFromDb);
45
46
        // If we found a user and he has a correct MD5 or correct new hash, then return the user
47 2
        if (($isMd5 && md5($password) === $hashFromDb) || password_verify($password, $hashFromDb)) {
48
49
            // Update the hash in DB, if we are still MD5, or if PHP default options changed
50 2
            if ($isMd5 || password_needs_rehash($hashFromDb, PASSWORD_DEFAULT)) {
51 2
                $user->setPassword($password);
52
            }
53 2
            $user->revokeToken();
54 2
            _em()->flush();
55
56 2
            return $user;
57
        }
58
59 1
        return null;
60
    }
61
62
    /**
63
     * Unsecured way to get a user from its ID.
64
     *
65
     * This should only be used in tests or controlled environment.
66
     */
67 19
    public function getOneById(int $id): ?User
68
    {
69
        $user = $this->getAclFilter()->runWithoutAcl(function () use ($id) {
70 19
            return $this->findOneById($id);
71 19
        });
72
73 19
        return $user;
74
    }
75
76
    /**
77
     * Unsecured way to get a user from its login.
78
     *
79
     * This should only be used in tests or controlled environment.
80
     */
81 88
    public function getOneByLogin(?string $login): ?User
82
    {
83
        $user = $this->getAclFilter()->runWithoutAcl(function () use ($login) {
84 88
            return $this->findOneByLogin($login);
85 88
        });
86
87 88
        return $user;
88
    }
89
90
    /**
91
     * Get all administrators to notify by email
92
     *
93
     * @return User[]
94
     */
95 2
    public function getAllAdministratorsToNotify(): array
96
    {
97 2
        $qb = $this->createQueryBuilder('user')
98 2
            ->andWhere('user.status = :status')
99 2
            ->andWhere('user.role = :role')
100 2
            ->andWhere("user.email IS NOT NULL AND user.email != ''")
101 2
            ->setParameter('status', User::STATUS_ACTIVE)
102 2
            ->setParameter('role', User::ROLE_ADMINISTRATOR);
103
104
        $result = $this->getAclFilter()->runWithoutAcl(function () use ($qb) {
105 2
            return $qb->getQuery()->getResult();
106 2
        });
107
108 2
        return $result;
109
    }
110
111 4
    public function getAllToQueueBalanceMessage(bool $onlyNegativeBalance = false): array
112
    {
113 4
        $qb = $this->createQueryBuilder('user')
114 4
            ->addSelect('account')
115 4
            ->addSelect('booking')
116 4
            ->addSelect('bookable')
117 4
            ->join('user.accounts', 'account')
118 4
            ->join('user.bookings', 'booking')
119 4
            ->join('booking.bookable', 'bookable')
120 4
            ->andWhere('user.status != :status')
121 4
            ->andWhere("user.email IS NOT NULL AND user.email != ''")
122 4
            ->andWhere('bookable.bookingType IN (:bookingType)')
123 4
            ->andWhere('bookable.isActive = true')
124 4
            ->andWhere('bookable.periodicPrice != 0')
125 4
            ->setParameter('bookingType', [BookingTypeType::MANDATORY, BookingTypeType::ADMIN_ONLY], Connection::PARAM_STR_ARRAY)
126 4
            ->setParameter('status', User::STATUS_ARCHIVED)
127 4
            ->addOrderBy('user.id')
128 4
            ->addOrderBy('bookable.name');
129
130 4
        if ($onlyNegativeBalance) {
131 2
            $qb->andWhere('account.balance < 0');
132
        }
133
134
        $result = $this->getAclFilter()->runWithoutAcl(function () use ($qb) {
135 4
            return $qb->getQuery()->getResult();
136 4
        });
137
138 4
        return $result;
139
    }
140
141
    /**
142
     * Return all users that are family owners (and should have Account)
143
     *
144
     * @return User[]
145
     */
146 1
    public function getAllFamilyOwners(): array
147
    {
148 1
        $qb = $this->createQueryBuilder('user')
149 1
            ->andWhere('user.owner IS NULL OR user.owner = user')
150 1
            ->addOrderBy('user.id');
151
152 1
        return $qb->getQuery()->getResult();
153
    }
154
155
    /**
156
     * Return all users that are not family owners but still have an Account
157
     *
158
     * @return User[]
159
     */
160 1
    public function getAllNonFamilyOwnersWithAccount(): array
161
    {
162 1
        $qb = $this->createQueryBuilder('user')
163 1
            ->join('user.accounts', 'account')
164 1
            ->andWhere('user.owner IS NOT NULL AND user.owner != user')
165 1
            ->addOrderBy('user.id');
166
167 1
        return $qb->getQuery()->getResult();
168
    }
169
}
170