Completed
Push — development ( 9736ae...1c21f9 )
by Mirco
24s queued 10s
created

UserRepository::fetchOneByUsername()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 24
rs 9.536
c 0
b 0
f 0
1
<?php
2
3
namespace Oc\Repository;
4
5
use Doctrine\DBAL\Connection;
6
use Oc\Entity\UserEntity;
7
use Oc\Repository\Exception\RecordAlreadyExistsException;
8
use Oc\Repository\Exception\RecordNotFoundException;
9
use Oc\Repository\Exception\RecordNotPersistedException;
10
use Oc\Repository\Exception\RecordsNotFoundException;
11
12
class UserRepository
13
{
14
    /**
15
     * Database table name that this repository maintains.
16
     *
17
     * @var string
18
     */
19
    public const TABLE = 'user';
20
21
    /**
22
     * @var Connection
23
     */
24
    private $connection;
25
    /**
26
     * @var SecurityRolesRepository
27
     */
28
    private $securityRolesRepository;
29
30
    public function __construct(Connection $connection, SecurityRolesRepository  $securityRolesRepository)
31
    {
32
        $this->connection = $connection;
33
        $this->securityRolesRepository = $securityRolesRepository;
34
    }
35
36
    /**
37
     * Fetches all users.
38
     *
39
     * @throws RecordsNotFoundException Thrown when no records are found
40
     * @return UserEntity[]
41
     */
42
    public function fetchAll(): array
43
    {
44
        $statement = $this->connection->createQueryBuilder()
45
            ->select('*')
46
            ->from(self::TABLE)
47
            ->execute();
48
49
        $result = $statement->fetchAll();
50
51
        if ($statement->rowCount() === 0) {
52
            throw new RecordsNotFoundException('No records found');
53
        }
54
55
        return $this->getEntityArrayFromDatabaseArray($result);
56
    }
57
58
    /**
59
     * Fetches a user by its id.
60
     *
61
     * @throws RecordNotFoundException Thrown when the request record is not found
62
     */
63
    public function fetchOneById(int $id): UserEntity
64
    {
65
        $statement = $this->connection->createQueryBuilder()
66
            ->select('*')
67
            ->from(self::TABLE)
68
            ->where('user_id = :id')
69
            ->setParameter(':id', $id)
70
            ->execute();
71
72
        $result = $statement->fetch();
73
74
        if ($statement->rowCount() === 0) {
75
            throw new RecordNotFoundException(sprintf(
76
                'Record with id #%s not found',
77
                $id
78
            ));
79
        }
80
81
        return $this->getEntityFromDatabaseArray($result);
82
    }
83
84
    /**
85
     * Fetches a user by its username.
86
     *
87
     * @throws RecordNotFoundException Thrown when the request record is not found
88
     */
89
    public function fetchOneByUsername(string $username): UserEntity
90
    {
91
        $statement = $this->connection->createQueryBuilder()
92
            ->select('*')
93
            ->from(self::TABLE)
94
            ->where('username = :username')
95
            ->setParameter(':username', $username)
96
            ->execute();
97
98
        $result = $statement->fetch();
99
100
        if ($statement->rowCount() === 0) {
101
            throw new RecordNotFoundException(sprintf(
102
                'Record with username "%s" not found',
103
                $username
104
            ));
105
        }
106
107
        $user = $this->getEntityFromDatabaseArray($result);
108
109
        $user->roles = $this->securityRolesRepository->fetchUserRoles($user);
110
111
        return $user;
112
    }
113
114
    /**
115
     * Creates a user in the database.
116
     *
117
     * @throws RecordAlreadyExistsException
118
     */
119
    public function create(UserEntity $entity): UserEntity
120
    {
121
        if (!$entity->isNew()) {
122
            throw new RecordAlreadyExistsException('The user entity already exists');
123
        }
124
125
        $databaseArray = $this->getDatabaseArrayFromEntity($entity);
126
127
        $this->connection->insert(
128
            self::TABLE,
129
            $databaseArray
130
        );
131
132
        $entity->id = (int) $this->connection->lastInsertId();
133
134
        return $entity;
135
    }
136
137
    /**
138
     * Update a user in the database.
139
     *
140
     * @throws RecordNotPersistedException
141
     */
142
    public function update(UserEntity $entity): UserEntity
143
    {
144
        if ($entity->isNew()) {
145
            throw new RecordNotPersistedException('The entity does not exist.');
146
        }
147
148
        $databaseArray = $this->getDatabaseArrayFromEntity($entity);
149
150
        $this->connection->update(
151
            self::TABLE,
152
            $databaseArray,
153
            ['id' => $entity->id]
154
        );
155
156
        $entity->id = (int) $this->connection->lastInsertId();
157
158
        return $entity;
159
    }
160
161
    /**
162
     * Removes a user from the database.
163
     *
164
     * @throws RecordNotPersistedException
165
     */
166
    public function remove(UserEntity $entity): UserEntity
167
    {
168
        if ($entity->isNew()) {
169
            throw new RecordNotPersistedException('The entity does not exist.');
170
        }
171
172
        $this->connection->delete(
173
            self::TABLE,
174
            ['id' => $entity->id]
175
        );
176
177
        $entity->id = null;
178
179
        return $entity;
180
    }
181
182
    /**
183
     * Converts database array to entity array.
184
     *
185
     * @return UserEntity[]
186
     */
187
    private function getEntityArrayFromDatabaseArray(array $result): array
188
    {
189
        $languages = [];
190
191
        foreach ($result as $item) {
192
            $languages[] = $this->getEntityFromDatabaseArray($item);
193
        }
194
195
        return $languages;
196
    }
197
198
    /**
199
     * Maps the given entity to the database array.
200
     */
201
    public function getDatabaseArrayFromEntity(UserEntity $entity): array
202
    {
203
        return [
204
            'user_id' => $entity->id,
205
            'username' => $entity->username,
206
            'password' => $entity->password,
207
            'email' => $entity->email,
208
            'latitude' => $entity->latitude,
209
            'longitude' => $entity->longitude,
210
            'is_active_flag' => $entity->isActive,
211
            'first_name' => $entity->firstname,
212
            'last_name' => $entity->lastname,
213
            'country' => $entity->country,
214
            'language' => $entity->language,
215
        ];
216
    }
217
218
    /**
219
     * Prepares database array from properties.
220
     */
221
    public function getEntityFromDatabaseArray(array $data): UserEntity
222
    {
223
        $entity = new UserEntity();
224
        $entity->id = (int) $data['user_id'];
225
        $entity->username = $data['username'];
226
        $entity->password = $data['password'];
227
        $entity->email = $data['email'];
228
        $entity->latitude = (double) $data['latitude'];
229
        $entity->longitude = (double) $data['longitude'];
230
        $entity->isActive = (bool) $data['is_active_flag'];
231
        $entity->firstname = $data['first_name'];
232
        $entity->lastname = $data['last_name'];
233
        $entity->country = $data['country'];
234
        $entity->language = strtolower($data['language']);
235
236
        return $entity;
237
    }
238
}
239