Completed
Push — development ( daed94...13a157 )
by Thomas
18s
created

FieldNoteRepository::remove()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 15
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 1
dl 15
loc 15
rs 9.4285
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
class FieldNoteRepository
14
{
15
    /**
16
     * Database table name that this repository maintains.
17
     *
18
     * @var string
19
     */
20
    const TABLE = 'field_note';
21
22
    /**
23
     * @var Connection
0 ignored issues
show
introduced by
Connection => \Doctrine\DBAL\Connection
Loading history...
24
     */
25
    private $connection;
26
    /**
27
     * @var GeoCacheRepository
0 ignored issues
show
introduced by
GeoCacheRepository => \Oc\GeoCache\Persistence\GeoCache\GeoCacheRepository
Loading history...
28
     */
29
    private $geoCacheRepository;
0 ignored issues
show
introduced by
Expected 1 blank line before member var with comment; 0 found
Loading history...
30
31
    /**
32
     * @param Connection $connection
0 ignored issues
show
introduced by
Connection => \Doctrine\DBAL\Connection
Loading history...
33
     * @param GeoCacheRepository $geoCacheRepository
0 ignored issues
show
introduced by
GeoCacheRepository => \Oc\GeoCache\Persistence\GeoCache\GeoCacheRepository
Loading history...
34
     */
35
    public function __construct(Connection $connection, GeoCacheRepository $geoCacheRepository)
36
    {
37
        $this->connection = $connection;
38
        $this->geoCacheRepository = $geoCacheRepository;
39
    }
40
41
    /**
42
     * Fetches all countries.
43
     *
44
     * @return FieldNoteEntity[]
0 ignored issues
show
introduced by
FieldNoteEntity[] => \Array\FieldNoteEntity[]
Loading history...
45
     *
46
     * @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...
47
     */
48 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...
49
    {
50
        $statement = $this->connection->createQueryBuilder()
51
            ->select('*')
52
            ->from(self::TABLE)
53
            ->execute();
54
55
        $result = $statement->fetchAll();
56
57
        if ($statement->rowCount() === 0) {
58
            throw new RecordsNotFoundException('No records found');
59
        }
60
61
        $entities = [];
62
63
        foreach ($result as $item) {
64
            $entities[] = $this->getEntityFromDatabaseArray($item);
65
        }
66
67
        return $entities;
68
    }
69
70
    /**
0 ignored issues
show
Coding Style Documentation introduced by
Doc comment for parameter "$order" missing
Loading history...
71
     * Fetches all GeoCaches by given where clause.
72
     *
73
     * @param array $where
74
     *
75
     * @return FieldNoteEntity[]
0 ignored issues
show
introduced by
FieldNoteEntity[] => \Array\FieldNoteEntity[]
Loading history...
76
     *
77
     * @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...
78
     */
79
    public function fetchBy(array $where = [], array $order = [])
0 ignored issues
show
introduced by
Doc Block params do not match method signature
Loading history...
80
    {
81
        $queryBuilder = $this->connection->createQueryBuilder()
82
            ->select('*')
83
            ->from(self::TABLE);
84
85
        foreach ($where as $column => $value) {
86
            $queryBuilder->andWhere($column . ' = ' .  $queryBuilder->createNamedParameter($value));
0 ignored issues
show
introduced by
Expected 1 space after ., but 2 found
Loading history...
87
        }
88
89
        foreach ($order as $field => $direction) {
90
            $queryBuilder->addOrderBy($field, $direction);
91
        }
92
93
        $statement = $queryBuilder->execute();
94
95
        $result = $statement->fetchAll();
96
97
        if ($statement->rowCount() === 0) {
98
            throw new RecordsNotFoundException('No records with given where clause found');
99
        }
100
101
        $entities = [];
102
103
        foreach ($result as $item) {
104
            $entities[] = $this->getEntityFromDatabaseArray($item);
105
        }
106
107
        return $entities;
108
    }
109
110
    /**
111
     * Fetches a field note by given where clause.
112
     *
113
     * @param array $where
114
     *
115
     * @return null|FieldNoteEntity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
116
     *
117
     * @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...
118
     */
119 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...
120
    {
121
        $queryBuilder = $this->connection->createQueryBuilder()
122
            ->select('*')
123
            ->from(self::TABLE)
124
            ->setMaxResults(1);
125
126
        if (count($where) > 0) {
127
            foreach ($where as $column => $value) {
128
                $queryBuilder->andWhere($column . ' = ' .  $queryBuilder->createNamedParameter($value));
0 ignored issues
show
introduced by
Expected 1 space after ., but 2 found
Loading history...
129
            }
130
        }
131
132
        $statement = $queryBuilder->execute();
133
134
        $result = $statement->fetch();
135
136
        if ($statement->rowCount() === 0) {
137
            throw new RecordNotFoundException('Record with given where clause not found');
138
        }
139
140
        return $this->getEntityFromDatabaseArray($result);
141
    }
142
143
    /**
144
     * Fetch latest user field note.
145
     *
146
     * @param int $userId
147
     *
148
     * @return FieldNoteEntity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
149
     *
150
     * @throws RecordNotFoundException
0 ignored issues
show
introduced by
RecordNotFoundException => \Oc\Repository\Exception\RecordNotFoundException
Loading history...
151
     */
152 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...
153
    {
154
        $queryBuilder = $this->connection->createQueryBuilder()
155
            ->select('*')
156
            ->from(self::TABLE)
157
            ->where('user_id = :userId')
158
            ->orderBy('date', 'DESC')
159
            ->setParameter('userId', $userId)
160
            ->setMaxResults(1);
161
162
        $statement = $queryBuilder->execute();
163
164
        $result = $statement->fetch();
165
166
        if ($statement->rowCount() === 0) {
167
            throw new RecordNotFoundException('Record with given where clause not found');
168
        }
169
170
        return $this->getEntityFromDatabaseArray($result);
171
    }
172
173
    /**
174
     * Creates a field note in the database.
175
     *
176
     * @param FieldNoteEntity $entity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
177
     *
178
     * @return FieldNoteEntity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
179
     *
180
     * @throws RecordAlreadyExistsException
0 ignored issues
show
introduced by
RecordAlreadyExistsException => \Oc\Repository\Exception\RecordAlreadyExistsException
Loading history...
181
     */
182 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...
183
    {
184
        if (!$entity->isNew()) {
185
            throw new RecordAlreadyExistsException('The entity does already exist.');
186
        }
187
188
        $databaseArray = $this->getDatabaseArrayFromEntity($entity);
189
190
        $this->connection->insert(
191
            self::TABLE,
192
            $databaseArray
193
        );
194
195
        $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...
196
197
        return $entity;
198
    }
199
200
    /**
201
     * Update a field note in the database.
202
     *
203
     * @param FieldNoteEntity $entity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
204
     *
205
     * @return FieldNoteEntity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
206
     *
207
     * @throws RecordNotPersistedException
0 ignored issues
show
introduced by
RecordNotPersistedException => \Oc\Repository\Exception\RecordNotPersistedException
Loading history...
208
     */
209
    public function update(FieldNoteEntity $entity)
210
    {
211
        if ($entity->isNew()) {
212
            throw new RecordNotPersistedException('The entity does not exist.');
213
        }
214
215
        $databaseArray = $this->getDatabaseArrayFromEntity($entity);
216
217
        $this->connection->update(
218
            self::TABLE,
219
            $databaseArray,
220
            ['id' => $entity->id]
221
        );
222
223
        $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...
224
225
        return $entity;
226
    }
227
228
    /**
229
     * Removes a field note from the database.
230
     *
231
     * @param FieldNoteEntity $entity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
232
     *
233
     * @return FieldNoteEntity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
234
     *
235
     * @throws RecordNotPersistedException
0 ignored issues
show
introduced by
RecordNotPersistedException => \Oc\Repository\Exception\RecordNotPersistedException
Loading history...
236
     */
237 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...
238
    {
239
        if ($entity->isNew()) {
240
            throw new RecordNotPersistedException('The entity does not exist.');
241
        }
242
243
        $this->connection->delete(
244
            self::TABLE,
245
            ['id' => $entity->id]
246
        );
247
248
        $entity->id = null;
249
250
        return $entity;
251
    }
252
253
    /**
254
     * Maps the given entity to the database array.
255
     *
256
     * @param FieldNoteEntity $entity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
257
     *
258
     * @return array
259
     */
260
    public function getDatabaseArrayFromEntity(FieldNoteEntity $entity)
261
    {
262
        return [
263
            'id' => $entity->id,
264
            'user_id' => $entity->userId,
265
            'geocache_id' => $entity->geocacheId,
266
            'type' => $entity->type,
267
            'date' => $entity->date->format(DateTime::ATOM),
268
            'text' => $entity->text
269
        ];
270
    }
271
272
    /**
273
     * Prepares database array from properties.
274
     *
275
     * @param array $data
276
     *
277
     * @return FieldNoteEntity
0 ignored issues
show
introduced by
FieldNoteEntity => \Array\FieldNoteEntity
Loading history...
278
     */
279
    public function getEntityFromDatabaseArray(array $data)
280
    {
281
        $entity = new FieldNoteEntity();
282
        $entity->id = $data['id'];
283
        $entity->userId = $data['user_id'];
284
        $entity->geocacheId = $data['geocache_id'];
285
        $entity->type = $data['type'];
286
        $entity->date = new DateTime($data['date']);
287
        $entity->text = $data['text'];
288
        $entity->geoCache = $this->geoCacheRepository->fetchOneBy([
289
            'cache_id' => $entity->geocacheId
290
        ]);
291
292
        return $entity;
293
    }
294
}
295