Passed
Pull Request — development (#682)
by Nick
07:18
created

FieldNoteRepository::fetchBy()   B

Complexity

Conditions 5
Paths 12

Size

Total Lines 30
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 16
nc 12
nop 2
dl 0
loc 30
rs 8.439
c 0
b 0
f 0
1
<?php
2
3
namespace Oc\FieldNotes\Persistence;
4
5
use DateTime;
6
use Doctrine\DBAL\Connection;
7
use Oc\GeoCache\Persistence\GeoCache\GeoCacheRepository;
8
use Oc\Repository\Exception\RecordAlreadyExistsException;
9
use Oc\Repository\Exception\RecordNotFoundException;
10
use Oc\Repository\Exception\RecordNotPersistedException;
11
use Oc\Repository\Exception\RecordsNotFoundException;
12
13
/**
14
 * Class FieldNoteRepository
15
 *
16
 * @package Oc\FieldNotes\Persistence
0 ignored issues
show
introduced by
Unexpected tag type @package in doc block
Loading history...
17
 */
18
class FieldNoteRepository
19
{
20
    /**
21
     * Database table name that this repository maintains.
22
     *
23
     * @var string
24
     */
25
    const TABLE = 'field_note';
26
27
    /**
28
     * @var Connection
0 ignored issues
show
introduced by
Connection => \Doctrine\DBAL\Connection
Loading history...
29
     */
30
    private $connection;
31
    /**
32
     * @var GeoCacheRepository
0 ignored issues
show
introduced by
GeoCacheRepository => \Oc\GeoCache\Persistence\GeoCache\GeoCacheRepository
Loading history...
33
     */
34
    private $geoCacheRepository;
0 ignored issues
show
introduced by
Expected 1 blank line before member var with comment; 0 found
Loading history...
35
36
    /**
37
     * FieldNoteRepository constructor.
38
     *
39
     * @param Connection $connection
0 ignored issues
show
introduced by
Connection => \Doctrine\DBAL\Connection
Loading history...
40
     * @param GeoCacheRepository $geoCacheRepository
0 ignored issues
show
introduced by
GeoCacheRepository => \Oc\GeoCache\Persistence\GeoCache\GeoCacheRepository
Loading history...
41
     */
42
    public function __construct(Connection $connection, GeoCacheRepository $geoCacheRepository)
43
    {
44
        $this->connection = $connection;
45
        $this->geoCacheRepository = $geoCacheRepository;
46
    }
47
48
    /**
49
     * Fetches all countries.
50
     *
51
     * @return FieldNoteEntity[]
0 ignored issues
show
introduced by
FieldNoteEntity[] => \Array\FieldNoteEntity[]
Loading history...
52
     *
53
     * @throws RecordsNotFoundException Thrown when no records are found
0 ignored issues
show
introduced by
RecordsNotFoundException => \Oc\Repository\Exception\RecordsNotFoundException
Loading history...
Coding Style introduced by
@throws tag comment must end with a full stop
Loading history...
54
     */
55 View Code Duplication
    public function fetchAll()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
56
    {
57
        $statement = $this->connection->createQueryBuilder()
58
            ->select('*')
59
            ->from(self::TABLE)
60
            ->execute();
61
62
        $result = $statement->fetchAll();
63
64
        if ($statement->rowCount() === 0) {
65
            throw new RecordsNotFoundException('No records found');
66
        }
67
68
        $entities = [];
69
70
        foreach ($result as $item) {
71
            $entities[] = $this->getEntityFromDatabaseArray($item);
72
        }
73
74
        return $entities;
75
    }
76
77
    /**
0 ignored issues
show
Coding Style Documentation introduced by
Doc comment for parameter "$order" missing
Loading history...
78
     * Fetches all GeoCaches by given where clause.
79
     *
80
     * @param array $where
81
     *
82
     * @return FieldNoteEntity[]
0 ignored issues
show
introduced by
FieldNoteEntity[] => \Array\FieldNoteEntity[]
Loading history...
83
     *
84
     * @throws RecordsNotFoundException Thrown when no records are found
0 ignored issues
show
introduced by
RecordsNotFoundException => \Oc\Repository\Exception\RecordsNotFoundException
Loading history...
Coding Style introduced by
@throws tag comment must end with a full stop
Loading history...
85
     */
86
    public function fetchBy(array $where = [], array $order = [])
0 ignored issues
show
introduced by
Doc Block params do not match method signature
Loading history...
87
    {
88
        $queryBuilder = $this->connection->createQueryBuilder()
89
            ->select('*')
90
            ->from(self::TABLE);
91
92
        foreach ($where as $column => $value) {
93
            $queryBuilder->andWhere($column . ' = ' .  $queryBuilder->createNamedParameter($value));
0 ignored issues
show
introduced by
Expected 1 space after ., but 2 found
Loading history...
94
        }
95
96
        foreach ($order as $field => $direction) {
97
            $queryBuilder->addOrderBy($field, $direction);
98
        }
99
100
        $statement = $queryBuilder->execute();
101
102
        $result = $statement->fetchAll();
103
104
        if ($statement->rowCount() === 0) {
105
            throw new RecordsNotFoundException('No records with given where clause found');
106
        }
107
108
        $entities = [];
109
110
        foreach ($result as $item) {
111
            $entities[] = $this->getEntityFromDatabaseArray($item);
112
        }
113
114
        return $entities;
115
    }
116
117
    /**
118
     * Fetches a field note by given where clause.
119
     *
120
     * @param array $where
121
     *
122
     * @return null|FieldNoteEntity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
123
     *
124
     * @throws RecordNotFoundException Thrown when no record is found
0 ignored issues
show
introduced by
RecordNotFoundException => \Oc\Repository\Exception\RecordNotFoundException
Loading history...
Coding Style introduced by
@throws tag comment must end with a full stop
Loading history...
125
     */
126 View Code Duplication
    public function fetchOneBy(array $where = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
127
    {
128
        $queryBuilder = $this->connection->createQueryBuilder()
129
            ->select('*')
130
            ->from(self::TABLE)
131
            ->setMaxResults(1);
132
133
        if (count($where) > 0) {
134
            foreach ($where as $column => $value) {
135
                $queryBuilder->andWhere($column . ' = ' .  $queryBuilder->createNamedParameter($value));
0 ignored issues
show
introduced by
Expected 1 space after ., but 2 found
Loading history...
136
            }
137
        }
138
139
        $statement = $queryBuilder->execute();
140
141
        $result = $statement->fetch();
142
143
        if ($statement->rowCount() === 0) {
144
            throw new RecordNotFoundException('Record with given where clause not found');
145
        }
146
147
        return $this->getEntityFromDatabaseArray($result);
148
    }
149
150
    /**
151
     * Fetch latest user field note.
152
     *
153
     * @param int $userId
154
     *
155
     * @return FieldNoteEntity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
156
     *
157
     * @throws RecordNotFoundException
0 ignored issues
show
introduced by
RecordNotFoundException => \Oc\Repository\Exception\RecordNotFoundException
Loading history...
158
     */
159 View Code Duplication
    public function getLatestUserFieldNote($userId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
160
    {
161
        $queryBuilder = $this->connection->createQueryBuilder()
162
            ->select('*')
163
            ->from(self::TABLE)
164
            ->where('user_id = :userId')
165
            ->orderBy('date', 'DESC')
166
            ->setParameter('userId', $userId)
167
            ->setMaxResults(1);
168
169
        $statement = $queryBuilder->execute();
170
171
        $result = $statement->fetch();
172
173
        if ($statement->rowCount() === 0) {
174
            throw new RecordNotFoundException('Record with given where clause not found');
175
        }
176
177
        return $this->getEntityFromDatabaseArray($result);
178
    }
179
180
    /**
181
     * Creates a field note in the database.
182
     *
183
     * @param FieldNoteEntity $entity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
184
     *
185
     * @return FieldNoteEntity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
186
     *
187
     * @throws RecordAlreadyExistsException
0 ignored issues
show
introduced by
RecordAlreadyExistsException => \Oc\Repository\Exception\RecordAlreadyExistsException
Loading history...
188
     */
189 View Code Duplication
    public function create(FieldNoteEntity $entity)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
190
    {
191
        if (!$entity->isNew()) {
192
            throw new RecordAlreadyExistsException('The entity does already exist.');
193
        }
194
195
        $databaseArray = $this->getDatabaseArrayFromEntity($entity);
196
197
        $this->connection->insert(
198
            self::TABLE,
199
            $databaseArray
200
        );
201
202
        $entity->id = $this->connection->lastInsertId();
0 ignored issues
show
Documentation Bug introduced by
The property $id was declared of type integer, but $this->connection->lastInsertId() is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
203
204
        return $entity;
205
    }
206
207
    /**
208
     * Update a field note in the database.
209
     *
210
     * @param FieldNoteEntity $entity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
211
     *
212
     * @return FieldNoteEntity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
213
     *
214
     * @throws RecordNotPersistedException
0 ignored issues
show
introduced by
RecordNotPersistedException => \Oc\Repository\Exception\RecordNotPersistedException
Loading history...
215
     */
216
    public function update(FieldNoteEntity $entity)
217
    {
218
        if ($entity->isNew()) {
219
            throw new RecordNotPersistedException('The entity does not exist.');
220
        }
221
222
        $databaseArray = $this->getDatabaseArrayFromEntity($entity);
223
224
        $this->connection->update(
225
            self::TABLE,
226
            $databaseArray,
227
            ['id' => $entity->id]
228
        );
229
230
        $entity->id = $this->connection->lastInsertId();
0 ignored issues
show
Documentation Bug introduced by
The property $id was declared of type integer, but $this->connection->lastInsertId() is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
231
232
        return $entity;
233
    }
234
235
    /**
236
     * Removes a field note from the database.
237
     *
238
     * @param FieldNoteEntity $entity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
239
     *
240
     * @return FieldNoteEntity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
241
     *
242
     * @throws RecordNotPersistedException
0 ignored issues
show
introduced by
RecordNotPersistedException => \Oc\Repository\Exception\RecordNotPersistedException
Loading history...
243
     */
244 View Code Duplication
    public function remove(FieldNoteEntity $entity)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
245
    {
246
        if ($entity->isNew()) {
247
            throw new RecordNotPersistedException('The entity does not exist.');
248
        }
249
250
        $this->connection->delete(
251
            self::TABLE,
252
            ['id' => $entity->id]
253
        );
254
255
        $entity->id = null;
256
257
        return $entity;
258
    }
259
260
    /**
261
     * Maps the given entity to the database array.
262
     *
263
     * @param FieldNoteEntity $entity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
264
     *
265
     * @return array
266
     */
267
    public function getDatabaseArrayFromEntity(FieldNoteEntity $entity)
268
    {
269
        return [
270
            'id' => $entity->id,
271
            'user_id' => $entity->userId,
272
            'geocache_id' => $entity->geocacheId,
273
            'type' => $entity->type,
274
            'date' => $entity->date->format(DateTime::ATOM),
275
            'text' => $entity->text
276
        ];
277
    }
278
279
    /**
280
     * Prepares database array from properties.
281
     *
282
     * @param array $data
283
     *
284
     * @return FieldNoteEntity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
285
     */
286
    public function getEntityFromDatabaseArray(array $data)
287
    {
288
        $entity = new FieldNoteEntity();
289
        $entity->id = (string) $data['id'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
Documentation Bug introduced by
The property $id was declared of type integer, but (string) $data['id'] is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
290
        $entity->userId = $data['user_id'];
291
        $entity->geocacheId = $data['geocache_id'];
292
        $entity->type = $data['type'];
293
        $entity->date = new DateTime($data['date']);
294
        $entity->text = $data['text'];
295
        $entity->geoCache = $this->geoCacheRepository->fetchOneBy([
296
            'cache_id' => $entity->geocacheId
297
        ]);
298
299
        return $entity;
300
    }
301
}
302