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

GeoCacheRepository::getDatabaseArrayFromEntity()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 40
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 37
nc 1
nop 1
dl 0
loc 40
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace Oc\GeoCache\Persistence\GeoCache;
4
5
use DateTime;
6
use Doctrine\DBAL\Connection;
7
use Oc\GeoCache\Enum\WaypointType;
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 GeoCacheRepository
15
 *
16
 * @package Oc\GeoCache\Persistence\GeoCache
0 ignored issues
show
introduced by
Unexpected tag type @package in doc block
Loading history...
17
 */
18
class GeoCacheRepository
19
{
20
    /**
21
     * Database table name that this repository maintains.
22
     *
23
     * @var string
24
     */
25
    const TABLE = 'caches';
26
27
    /**
28
     * @var Connection
0 ignored issues
show
introduced by
Connection => \Doctrine\DBAL\Connection
Loading history...
29
     */
30
    private $connection;
31
32
    /**
33
     * GeoCacheRepository constructor.
34
     *
35
     * @param Connection $connection
0 ignored issues
show
introduced by
Connection => \Doctrine\DBAL\Connection
Loading history...
36
     */
37
    public function __construct(Connection $connection)
38
    {
39
        $this->connection = $connection;
40
    }
41
42
    /**
43
     * Fetches all GeoCaches.
44
     *
45
     * @return GeoCacheEntity[]
0 ignored issues
show
introduced by
GeoCacheEntity[] => \Array\GeoCacheEntity[]
Loading history...
46
     *
47
     * @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...
48
     */
49 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...
50
    {
51
        $statement = $this->connection->createQueryBuilder()
52
            ->select('*')
53
            ->from(self::TABLE)
54
            ->execute();
55
56
        $result = $statement->fetchAll();
57
58
        if ($statement->rowCount() === 0) {
59
            throw new RecordsNotFoundException('No records found');
60
        }
61
62
        $records = [];
63
64
        foreach ($result as $item) {
65
            $records[] = $this->getEntityFromDatabaseArray($item);
66
        }
67
68
        return $records;
69
    }
70
71
    /**
72
     * Fetches a GeoCache by given where clause.
73
     *
74
     * @param array $where
75
     *
76
     * @return null|GeoCacheEntity
0 ignored issues
show
introduced by
GeoCacheEntity => \Array\GeoCacheEntity
Loading history...
77
     *
78
     * @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...
79
     */
80 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...
81
    {
82
        $queryBuilder = $this->connection->createQueryBuilder()
83
             ->select('*')
84
             ->from(self::TABLE)
85
             ->setMaxResults(1);
86
87
        if (count($where) > 0) {
88
            foreach ($where as $column => $value) {
89
                $queryBuilder->andWhere($column . ' = ' .  $queryBuilder->createNamedParameter($value));
0 ignored issues
show
introduced by
Expected 1 space after ., but 2 found
Loading history...
90
            }
91
        }
92
93
        $statement = $queryBuilder->execute();
94
95
        $result = $statement->fetch();
96
97
        if ($statement->rowCount() === 0) {
98
            throw new RecordNotFoundException('Record with given where clause not found');
99
        }
100
101
        return $this->getEntityFromDatabaseArray($result);
102
    }
103
104
    /**
105
     * Fetches all GeoCaches by given where clause.
106
     *
107
     * @param array $where
108
     *
109
     * @return GeoCacheEntity[]
0 ignored issues
show
introduced by
GeoCacheEntity[] => \Array\GeoCacheEntity[]
Loading history...
110
     *
111
     * @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...
112
     */
113 View Code Duplication
    public function fetchBy(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...
114
    {
115
        $queryBuilder = $this->connection->createQueryBuilder()
116
             ->select('*')
117
             ->from(self::TABLE);
118
119
        if (count($where) > 0) {
120
            foreach ($where as $column => $value) {
121
                $queryBuilder->andWhere($column . ' = ' .  $queryBuilder->createNamedParameter($value));
0 ignored issues
show
introduced by
Expected 1 space after ., but 2 found
Loading history...
122
            }
123
        }
124
125
        $statement = $queryBuilder->execute();
126
127
        $result = $statement->fetchAll();
128
129
        if ($statement->rowCount() === 0) {
130
            throw new RecordsNotFoundException('No records with given where clause found');
131
        }
132
133
        $geoCaches = [];
134
135
        foreach ($result as $item) {
136
            $geoCaches[] = $this->getEntityFromDatabaseArray($item);
137
        }
138
139
        return $geoCaches;
140
    }
141
142
    /**
143
     * Fetches a GeoCache by given where clause.
144
     *
145
     * @param string $waypoint
146
     *
147
     * @return null|GeoCacheEntity
0 ignored issues
show
introduced by
GeoCacheEntity => \Array\GeoCacheEntity
Loading history...
148
     *
149
     * @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...
150
     */
151
    public function fetchGCWaypoint($waypoint)
152
    {
153
        if (WaypointType::guess($waypoint) !== WaypointType::GC) {
154
            throw new RecordNotFoundException('Record by given gc waypoint not found');
155
        }
156
157
        $queryBuilder = $this->connection->createQueryBuilder()
158
            ->select('*')
159
            ->from(self::TABLE)
160
            ->where("IFELSE(wp_gc_maintained = '', wp_gc, g.wp_gc_maintained) = :waypoint")
161
            ->setParameter(':waypoint', $waypoint)
162
            ->setMaxResults(1);
163
164
        $statement = $queryBuilder->execute();
165
166
        $result = $statement->fetch();
167
168
        if ($statement->rowCount() === 0) {
169
            throw new RecordNotFoundException('Record by given gc waypoint not found');
170
        }
171
172
        return $this->getEntityFromDatabaseArray($result);
173
    }
174
175
    /**
176
     * Creates a GeoCache in the database.
177
     *
178
     * @param GeoCacheEntity $entity
0 ignored issues
show
introduced by
GeoCacheEntity => \Array\GeoCacheEntity
Loading history...
179
     *
180
     * @return GeoCacheEntity
0 ignored issues
show
introduced by
GeoCacheEntity => \Array\GeoCacheEntity
Loading history...
181
     *
182
     * @throws RecordAlreadyExistsException
0 ignored issues
show
introduced by
RecordAlreadyExistsException => \Oc\Repository\Exception\RecordAlreadyExistsException
Loading history...
183
     */
184
    public function create(GeoCacheEntity $entity)
185
    {
186
        if (!$entity->isNew()) {
187
            throw new RecordAlreadyExistsException('The entity does already exist.');
188
        }
189
190
        $databaseArray = $this->getDatabaseArrayFromEntity($entity);
191
192
        $this->connection->insert(
193
            self::TABLE,
194
            $databaseArray
195
        );
196
197
        $entity->cacheId = $this->connection->lastInsertId();
0 ignored issues
show
Documentation Bug introduced by
The property $cacheId 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...
198
199
        return $entity;
200
    }
201
202
    /**
203
     * Update a GeoCache in the database.
204
     *
205
     * @param GeoCacheEntity $entity
0 ignored issues
show
introduced by
GeoCacheEntity => \Array\GeoCacheEntity
Loading history...
206
     *
207
     * @return GeoCacheEntity
0 ignored issues
show
introduced by
GeoCacheEntity => \Array\GeoCacheEntity
Loading history...
208
     *
209
     * @throws RecordNotPersistedException
0 ignored issues
show
introduced by
RecordNotPersistedException => \Oc\Repository\Exception\RecordNotPersistedException
Loading history...
210
     */
211 View Code Duplication
    public function update(GeoCacheEntity $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...
212
    {
213
        if ($entity->isNew()) {
214
            throw new RecordNotPersistedException('The entity does not exist.');
215
        }
216
217
        $databaseArray = $this->getDatabaseArrayFromEntity($entity);
218
219
        $this->connection->update(
220
            self::TABLE,
221
            $databaseArray,
222
            ['cache_id' => $entity->cacheId]
223
        );
224
225
        $entity->cacheId = $this->connection->lastInsertId();
0 ignored issues
show
Documentation Bug introduced by
The property $cacheId 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...
226
227
        return $entity;
228
    }
229
230
    /**
231
     * Removes a GeoCache from the database.
232
     *
233
     * @param GeoCacheEntity $entity
0 ignored issues
show
introduced by
GeoCacheEntity => \Array\GeoCacheEntity
Loading history...
234
     *
235
     * @return GeoCacheEntity
0 ignored issues
show
introduced by
GeoCacheEntity => \Array\GeoCacheEntity
Loading history...
236
     *
237
     * @throws RecordNotPersistedException
0 ignored issues
show
introduced by
RecordNotPersistedException => \Oc\Repository\Exception\RecordNotPersistedException
Loading history...
238
     */
239 View Code Duplication
    public function remove(GeoCacheEntity $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...
240
    {
241
        if ($entity->isNew()) {
242
            throw new RecordNotPersistedException('The entity does not exist.');
243
        }
244
245
        $this->connection->delete(
246
            self::TABLE,
247
            ['cache_id' => $entity->cacheId]
248
        );
249
250
        $entity->cacheId = null;
251
252
        return $entity;
253
    }
254
255
    /**
256
     * Maps the given entity to the database array.
257
     *
258
     * @param GeoCacheEntity $entity
0 ignored issues
show
introduced by
GeoCacheEntity => \Array\GeoCacheEntity
Loading history...
259
     *
260
     * @return array
261
     */
262
    public function getDatabaseArrayFromEntity(GeoCacheEntity $entity)
263
    {
264
        return [
265
            'cache_id' => $entity->cacheId,
266
            'uuid' => $entity->uuid,
267
            'node' => $entity->node,
268
            'date_created' => $entity->dateCreated->format(DateTime::ATOM),
269
            'is_publishdate' => $entity->isPublishdate,
270
            'last_modified' => $entity->lastModified->format(DateTime::ATOM),
271
            'okapi_syncbase' => $entity->okapiSyncbase,
272
            'listing_last_modified' => $entity->listingLastModified->format(DateTime::ATOM),
273
            'meta_last_modified' => $entity->metaLastModified->format(DateTime::ATOM),
274
            'user_id' => $entity->userId,
275
            'name' => $entity->name,
276
            'longitude' => $entity->longitude,
277
            'latitude' => $entity->latitude,
278
            'type' => $entity->type,
279
            'status' => $entity->status,
280
            'country' => $entity->country,
281
            'date_hidden' => $entity->dateHidden->format(DateTime::ATOM),
282
            'size' => $entity->size,
283
            'difficulty' => $entity->difficulty,
284
            'terrain' => $entity->terrain,
285
            'logpw' => $entity->logpw,
286
            'search_time' => $entity->searchTime,
287
            'way_length' => $entity->wayLength,
288
            'wp_gc' => $entity->wpGc,
289
            'wp_gc_maintained' => $entity->wpGcMaintained,
290
            'wp_oc' => $entity->wpOc,
291
            'desc_languages' => $entity->descLanguages,
292
            'default_desclang' => $entity->defaultDesclang,
293
            'date_activate' => $entity->dateActivate->format(DateTime::ATOM),
294
            'need_npa_recalc' => $entity->needNpaRecalc,
295
            'show_cachelists' => $entity->showCachelists,
296
            'protect_old_coords' => $entity->protectOldCoords,
297
            'needs_maintenance' => $entity->needsMaintenance,
298
            'listing_outdated' => $entity->listingOutdated,
299
            'flags_last_modified' => $entity->flagsLastModified->format(DateTime::ATOM)
300
        ];
301
    }
302
303
    /**
304
     * Prepares database array from properties.
305
     *
306
     * @param array $data
307
     *
308
     * @return GeoCacheEntity
0 ignored issues
show
introduced by
GeoCacheEntity => \Array\GeoCacheEntity
Loading history...
309
     */
310
    public function getEntityFromDatabaseArray(array $data)
311
    {
312
        $entity = new GeoCacheEntity();
313
        $entity->cacheId = (string) $data['cache_id'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
Documentation Bug introduced by
The property $cacheId was declared of type integer, but (string) $data['cache_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...
314
        $entity->uuid = (string) $data['uuid'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
315
        $entity->node = (int) $data['node'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
316
        $entity->dateCreated = new DateTime($data['date_created']);
317
        $entity->isPublishdate = (bool) $data['is_publishdate'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
318
        $entity->lastModified = new DateTime($data['last_modified']);
319
        $entity->okapiSyncbase = (int) $data['okapi_syncbase'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
320
        $entity->listingLastModified = new DateTime($data['listing_last_modified']);
321
        $entity->metaLastModified = new DateTime($data['meta_last_modified']);
322
        $entity->userId = (int) $data['user_id'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
323
        $entity->name = (string) $data['name'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
324
        $entity->longitude = (double) $data['longitude'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
325
        $entity->latitude = (double) $data['latitude'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
326
        $entity->type = (int) $data['type'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
327
        $entity->status = (int) $data['status'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
328
        $entity->country = (string) $data['country'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
329
        $entity->dateHidden = new DateTime($data['date_hidden']);
330
        $entity->size = (int) $data['size'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
331
        $entity->difficulty = (int) $data['difficulty'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
332
        $entity->terrain = (int) $data['terrain'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
333
        $entity->logpw = (string) $data['logpw'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
334
        $entity->searchTime = (float) $data['search_time'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
335
        $entity->wayLength = (float) $data['way_length'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
336
        $entity->wpGc = (string) $data['wp_gc'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
337
        $entity->wpGcMaintained = (string) $data['wp_gc_maintained'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
338
        $entity->wpOc = (string) $data['wp_oc'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
339
        $entity->descLanguages = (string) $data['desc_languages'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
340
        $entity->defaultDesclang = (string) $data['default_desclang'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
341
        $entity->dateActivate = new DateTime($data['date_activate']);
342
        $entity->needNpaRecalc = (bool) $data['need_npa_recalc'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
Documentation Bug introduced by
The property $needNpaRecalc was declared of type integer, but (bool) $data['need_npa_recalc'] is of type boolean. 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...
343
        $entity->showCachelists = (bool) $data['show_cachelists'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
Documentation Bug introduced by
The property $showCachelists was declared of type integer, but (bool) $data['show_cachelists'] is of type boolean. 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...
344
        $entity->protectOldCoords = (bool) $data['protect_old_coords'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
Documentation Bug introduced by
The property $protectOldCoords was declared of type integer, but (bool) $data['protect_old_coords'] is of type boolean. 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...
345
        $entity->needsMaintenance = (bool) $data['needs_maintenance'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
Documentation Bug introduced by
The property $needsMaintenance was declared of type integer, but (bool) $data['needs_maintenance'] is of type boolean. 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...
346
        $entity->listingOutdated = (bool) $data['listing_outdated'];
0 ignored issues
show
introduced by
No whitespace should be between cast and variable.
Loading history...
Documentation Bug introduced by
The property $listingOutdated was declared of type integer, but (bool) $data['listing_outdated'] is of type boolean. 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...
347
        $entity->flagsLastModified = new DateTime($data['flags_last_modified']);
348
349
        return $entity;
350
    }
351
}
352