DatabaseUsersRepository.php 5.77 KB
Newer Older
Jacob Priddy's avatar
Jacob Priddy committed
1
2
3
4
5
<?php


namespace Source\Gateways\Users;

Jacob Priddy's avatar
Jacob Priddy committed
6
use Source\Entities\User;
Jacob Priddy's avatar
Jacob Priddy committed
7
use Source\Sanitize\CastsTo;
Jacob Priddy's avatar
Jacob Priddy committed
8
use Source\Entities\Password;
9
use Illuminate\Support\Facades\Log;
Jacob Priddy's avatar
Jacob Priddy committed
10
use Source\Entities\HashedSearchable;
11
use Source\Gateways\PostgresSQLCodes;
12
use Illuminate\Database\QueryException;
13
use Source\Exceptions\EntityExistsException;
Jacob Priddy's avatar
Jacob Priddy committed
14

Jacob Priddy's avatar
Jacob Priddy committed
15
16
class DatabaseUsersRepository implements UsersRepository
{
Jacob Priddy's avatar
Jacob Priddy committed
17
18
    use CastsTo;

19
20
21
22
23
    /**
     * @inheritDoc
     */
    public function get(string $userId): ?User
    {
24
        /** @var \App\User|null $user */
25
        $user = \App\User::query()->find(self::castToInt($userId));
26
27
28
29
30
31
32
33

        if (!$user) {
            return null;
        }

        return self::makeUserFromDbUser($user);
    }

34
35
36
37
    /**
     * @param \App\User $user
     * @return \Source\Entities\User
     */
38
    public static function makeUserFromDbUser(\App\User $user): User
Jacob Priddy's avatar
Jacob Priddy committed
39
    {
Jacob Priddy's avatar
Jacob Priddy committed
40
        return new User(
41
42
43
44
45
46
47
48
49
50
51
            $user->getAttribute('id'),
            $user->getAttribute('first_name'),
            $user->getAttribute('last_name'),
            $user->getAttribute('display_name'),
            $user->getAttribute('email'),
            $user->getAttribute('emplid'),
            $user->getAttribute('password') === null ? null : new Password($user->getAttribute('password')),
            $user->getAttribute('doorcode') === null ? null : new HashedSearchable($user->getAttribute('doorcode')),
            $user->getAttribute('expires_at'),
            $user->getAttribute('created_at'),
            $user->getAttribute('updated_at')
Jacob Priddy's avatar
Jacob Priddy committed
52
53
54
55
56
57
        );
    }

    /**
     * @inheritDoc
     */
58
    public function search(?string $query = null): array
Jacob Priddy's avatar
Jacob Priddy committed
59
    {
60
        $builder = \App\User::query()->orderBy('id');
61
        if (!$query) {
62
            $users = $builder->get()->values()->all();
63
        } else {
64
            $users = $builder
65
                ->where('first_name', 'ILIKE', "%$query%")
Jacob Priddy's avatar
Jacob Priddy committed
66
                ->orWhere('id', '=', self::castToInt($query))
67
68
69
70
71
72
                ->orWhere('last_name', 'ILIKE', "%$query%")
                ->orWhere('display_name', 'ILIKE', "%$query%")
                ->orWhere('email', 'ILIKE', "%$query%")
                ->orWhere('emplid', 'ILIKE', "%$query%")
                ->get()->values()->all();
        }
Jacob Priddy's avatar
Jacob Priddy committed
73

74
75
76
        return array_map(static function (\App\User $user) {
            return self::makeUserFromDbUser($user);
        }, $users);
Jacob Priddy's avatar
Jacob Priddy committed
77
78
79
    }

    /**
80
81
82
     * @param \App\User             $dbUser
     * @param \Source\Entities\User $user
     * @throws \Source\Exceptions\EntityExistsException
Jacob Priddy's avatar
Jacob Priddy committed
83
     */
84
    protected function saveUser(\App\User $dbUser, User $user): void
Jacob Priddy's avatar
Jacob Priddy committed
85
    {
86
        $dbUser = $this->fillBasicUserAttrs($user, $dbUser);
87

88
        try {
89
            $dbUser->save();
90
        } catch (QueryException $e) {
91
            if ($e->getCode() === PostgresSQLCodes::UNIQUE_CONSTRAINT_VIOLATION) {
92
                throw new EntityExistsException('Cannot save user. A user already has a specified unique attribute.');
93
94
            }

95
            Log::error('Failed saving user: ' . $e);
96
97
98

            throw $e;
        }
99
100
101
102
103
104
105
106
107
108
    }

    /**
     * @inheritDoc
     */
    public function create(User $user): ?User
    {
        $newUser = new \App\User();

        $this->saveUser($newUser, $user);
Jacob Priddy's avatar
Jacob Priddy committed
109

110
        return self::makeUserFromDbUser($newUser);
Jacob Priddy's avatar
Jacob Priddy committed
111
112
    }

113
114
115
116
117
118
    /**
     * @param \Source\Entities\User $user
     * @param \App\User             $dbUser
     * @return \App\User
     */
    protected function fillBasicUserAttrs(User $user, \App\User $dbUser): \App\User
Jacob Priddy's avatar
Jacob Priddy committed
119
    {
120
121
122
123
124
125
126
127
        $dbUser->setAttribute('first_name', $user->getFirstName());
        $dbUser->setAttribute('last_name', $user->getLastName());
        $dbUser->setAttribute('display_name', $user->getDisplayName());
        $dbUser->setAttribute('emplid', $user->getEmplid());
        $dbUser->setAttribute('email', $user->getEmail());
        $dbUser->setAttribute('expires_at', $user->getExpiresAt());
        $dbUser->setAttribute('password', $user->getPassword() === null ? null : $user->getPassword()->getHash());
        $dbUser->setAttribute('doorcode', $user->getDoorcode() === null ? null : $user->getDoorcode()->getHash());
128

Jacob Priddy's avatar
Jacob Priddy committed
129
130
131
        return $dbUser;
    }

Jacob Priddy's avatar
Jacob Priddy committed
132
133
134
    /**
     * @inheritDoc
     */
Jacob Priddy's avatar
Jacob Priddy committed
135
136
    public function update(string $userId, User $user): ?User
    {
137
        /** @var \App\User|null $dbUser */
138
        $dbUser = \App\User::query()->find(self::castToInt($userId));
Jacob Priddy's avatar
Jacob Priddy committed
139
140
141
142
143

        if (!$dbUser) {
            return null;
        }

144
        $this->saveUser($dbUser, $user);
Jacob Priddy's avatar
Jacob Priddy committed
145

146
        return self::makeUserFromDbUser($dbUser);
Jacob Priddy's avatar
Jacob Priddy committed
147
148
149
150
151
    }

    /**
     * @inheritDoc
     */
Jacob Priddy's avatar
Jacob Priddy committed
152
153
    public function delete(string $userId): bool
    {
154
        return \App\User::destroy(self::castToInt($userId));
Jacob Priddy's avatar
Jacob Priddy committed
155
156
157
158
159
    }

    /**
     * @inheritDoc
     */
Jacob Priddy's avatar
Jacob Priddy committed
160
161
    public function exists(string $userId): bool
    {
162
        return $this->get($userId) !== null;
Jacob Priddy's avatar
Jacob Priddy committed
163
164
165
166
167
    }

    /**
     * @inheritDoc
     */
168
    public function findByDoorcode(?HashedSearchable $doorcode): ?User
Jacob Priddy's avatar
Jacob Priddy committed
169
    {
Jacob Priddy's avatar
Jacob Priddy committed
170
        if (!$doorcode) {
Jacob Priddy's avatar
Jacob Priddy committed
171
172
173
            return null;
        }

174
175
        /** @var \App\User|null $user */
        $user = \App\User::query()->where('doorcode', $doorcode->getHash())->first();
Jacob Priddy's avatar
Jacob Priddy committed
176
177
178
179
180

        if (!$user) {
            return null;
        }

181
        return self::makeUserFromDbUser($user);
Jacob Priddy's avatar
Jacob Priddy committed
182
183
184
    }


185
186
187
    /**
     * @inheritDoc
     */
Jacob Priddy's avatar
Jacob Priddy committed
188
189
    public function findByEmail(string $email): ?User
    {
190
191
        /** @var \App\User|null $user */
        $user = \App\User::query()->where('email', strtolower($email))->first();
192

193
194
195
196
        if (!$user) {
            return null;
        }

197
        return self::makeUserFromDbUser($user);
198
    }
Jacob Priddy's avatar
Jacob Priddy committed
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

    /**
     * @inheritDoc
     */
    public function findByEmplid(string $emplid): ?User
    {
        /** @var \App\User|null $user */
        $user = \App\User::query()->where('emplid', $emplid)->first();

        if (!$user) {
            return null;
        }

        return self::makeUserFromDbUser($user);
    }
Jacob Priddy's avatar
Jacob Priddy committed
214
}