Passed
Pull Request — dev (#2044)
by Nico
11:37
created

StarSystemMapRepository::getByBoundaries()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 1
dl 0
loc 9
ccs 0
cts 7
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Orm\Repository;
6
7
use Doctrine\ORM\EntityRepository;
8
use Doctrine\ORM\Query\ResultSetMapping;
9
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Stu\Component\Building\BuildingFunctionEnum;
11
use Stu\Component\Ship\AstronomicalMappingEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Ship\AstronomicalMappingEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Stu\Component\Ship\FlightSignatureVisibilityEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Ship\FlightSignatureVisibilityEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
14
use Stu\Lib\Map\VisualPanel\PanelBoundaries;
15
use Stu\Module\PlayerSetting\Lib\UserEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Module\PlayerSetting\Lib\UserEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use Stu\Orm\Entity\StarSystemInterface;
17
use Stu\Orm\Entity\StarSystemMap;
18
use Stu\Orm\Entity\StarSystemMapInterface;
19
20
/**
21
 * @extends EntityRepository<StarSystemMap>
22
 */
23
final class StarSystemMapRepository extends EntityRepository implements StarSystemMapRepositoryInterface
24
{
25
    #[Override]
26
    public function getBySystemOrdered(int $starSystemId): array
27
    {
28
        return $this->findBy(
29
            ['systems_id' => $starSystemId],
30
            ['sy' => 'asc', 'sx' => 'asc']
31
        );
32
    }
33
34 2
    #[Override]
35
    public function getByCoordinates(
36
        int $starSystemId,
37
        int $sx,
38
        int $sy
39
    ): ?StarSystemMapInterface {
40 2
        return $this->findOneBy([
41 2
            'systems_id' => $starSystemId,
42 2
            'sx' => $sx,
43 2
            'sy' => $sy
44 2
        ]);
45
    }
46
47
    #[Override]
48
    public function getByBoundaries(PanelBoundaries $boundaries): array
49
    {
50
        return $this->getByCoordinateRange(
51
            $boundaries->getParentId(),
52
            $boundaries->getMinX(),
53
            $boundaries->getMaxX(),
54
            $boundaries->getMinY(),
55
            $boundaries->getMaxY()
56
        );
57
    }
58
59
    #[Override]
60
    public function getByCoordinateRange(
61
        int $starSystemId,
62
        int $startSx,
63
        int $endSx,
64
        int $startSy,
65
        int $endSy,
66
        bool $sortAscending = true
67
    ): array {
68
        return $this->getEntityManager()
69
            ->createQuery(
70
                sprintf(
71
                    'SELECT m FROM %1$s m
72
                    WHERE m.systems_id = :starSystemId AND
73
                        m.sx BETWEEN :startSx AND :endSx AND
74
                        m.sy BETWEEN :startSy AND :endSy
75
                    ORDER BY m.sy %2$s, m.sx %2$s',
76
                    StarSystemMap::class,
77
                    $sortAscending ? 'ASC' : 'DESC'
78
                )
79
            )
80
            ->setParameters([
81
                'starSystemId' => $starSystemId,
82
                'startSx' => $startSx,
83
                'endSx' => $endSx,
84
                'startSy' => $startSy,
85
                'endSy' => $endSy
86
            ])
87
            ->getResult();
88
    }
89
90 3
    #[Override]
91
    public function getMapLayerData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
92
    {
93 3
        return $this->getEntityManager()->createNativeQuery(
94 3
            'SELECT sm.sx as x, sm.sy AS y, ft.type
95
                FROM stu_sys_map sm
96
                JOIN stu_location l
97
                ON sm.id = l.id
98
                JOIN stu_map_ftypes ft ON ft.id = l.field_id
99
                WHERE sm.sx BETWEEN :xStart AND :xEnd AND sm.sy BETWEEN :yStart AND :yEnd
100 3
                AND sm.systems_id = :systemId',
101 3
            $rsm
102 3
        )->setParameters([
103 3
            'xStart' => $boundaries->getMinX(),
104 3
            'xEnd' => $boundaries->getMaxX(),
105 3
            'yStart' => $boundaries->getMinY(),
106 3
            'yEnd' => $boundaries->getMaxY(),
107 3
            'systemId' => $boundaries->getParentId()
108 3
        ])->getResult();
109
    }
110
111 3
    #[Override]
112
    public function getSpacecraftCountLayerData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
113
    {
114 3
        return $this->getEntityManager()->createNativeQuery(
115 3
            'SELECT sm.id, sm.sx as x, sm.sy AS y,
116
                (SELECT count(DISTINCT b.id) FROM stu_spacecraft b
117
                    WHERE sm.id = b.location_id
118
                    AND NOT EXISTS (SELECT ss.id
119
                                        FROM stu_spacecraft_system ss
120
                                        WHERE b.id = ss.spacecraft_id
121
                                        AND ss.system_type = :cloakSystemId
122
                                        AND ss.mode > 1)) AS spacecraftcount,
123
                (SELECT count(DISTINCT c.id) FROM stu_spacecraft c
124
                    WHERE sm.id = c.location_id
125
                    AND EXISTS (SELECT ss2.id
126
                                        FROM stu_spacecraft_system ss2
127
                                        WHERE c.id = ss2.spacecraft_id
128
                                        AND ss2.system_type = :cloakSystemId
129
                                        AND ss2.mode > 1)) AS cloakcount,
130
                (SELECT mft.effects FROM stu_map_ftypes mft
131
                WHERE l.field_id = mft.id) as effects
132
            FROM stu_sys_map sm
133
            JOIN stu_location l
134
            ON sm.id = l.id
135
            WHERE sm.sx BETWEEN :xStart AND :xEnd AND sm.sy BETWEEN :yStart AND :yEnd
136
            AND sm.systems_id = :systemId
137 3
            GROUP BY sm.id, sm.sy, sm.sx, l.field_id',
138 3
            $rsm
139 3
        )->setParameters([
140 3
            'xStart' => $boundaries->getMinX(),
141 3
            'xEnd' => $boundaries->getMaxX(),
142 3
            'yStart' => $boundaries->getMinY(),
143 3
            'yEnd' => $boundaries->getMaxY(),
144 3
            'systemId' => $boundaries->getParentId(),
145 3
            'cloakSystemId' => SpacecraftSystemTypeEnum::CLOAK->value
146 3
        ])->getResult();
147
    }
148
149 3
    #[Override]
150
    public function getColonyShieldData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
151
    {
152 3
        return $this->getEntityManager()->createNativeQuery(
153 3
            'SELECT sm.sx as x, sm.sy AS y,
154
            (SELECT COUNT(*) > 0
155
                FROM stu_colonies col
156
                JOIN stu_colonies_fielddata cfd
157
                ON col.id = cfd.colonies_id
158
                WHERE sm.id = col.starsystem_map_id
159
                AND cfd.aktiv = :active
160
                AND cfd.buildings_id IN (
161
                    SELECT bf.buildings_id
162
                    FROM stu_buildings_functions bf
163
                    WHERE bf.function = :shieldBuilding)) AS shieldstate
164
            FROM stu_sys_map sm
165
            WHERE sm.systems_id = :systemId
166 3
            AND sm.sx BETWEEN :xStart AND :xEnd AND sm.sy BETWEEN :yStart AND :yEnd',
167 3
            $rsm
168 3
        )->setParameters([
169 3
            'xStart' => $boundaries->getMinX(),
170 3
            'xEnd' => $boundaries->getMaxX(),
171 3
            'yStart' => $boundaries->getMinY(),
172 3
            'yEnd' => $boundaries->getMaxY(),
173 3
            'systemId' => $boundaries->getParentId(),
174 3
            'active' => 1,
175 3
            'shieldBuilding' => BuildingFunctionEnum::SHIELD_GENERATOR
176 3
        ])->getResult();
177
    }
178
179
    #[Override]
180
    public function getNormalBorderData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
181
    {
182
        return $this->getEntityManager()->createNativeQuery(
183
            'SELECT sm.sx AS x, sm.sy AS y
184
            FROM stu_sys_map sm
185
            WHERE sm.systems_id = :systemId
186
            AND sm.sx BETWEEN :xStart AND :xEnd
187
            AND sm.sy BETWEEN :yStart AND :yEnd',
188
            $rsm
189
        )->setParameters([
190
            'xStart' => $boundaries->getMinX(),
191
            'xEnd' => $boundaries->getMaxX(),
192
            'yStart' => $boundaries->getMinY(),
193
            'yEnd' => $boundaries->getMaxY(),
194
            'systemId' => $boundaries->getParentId()
195
        ])->getResult();
196
    }
197
198
    #[Override]
199
    public function getRegionBorderData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
200
    {
201
        return $this->getEntityManager()->createNativeQuery(
202
            'SELECT sm.sx AS x, sm.sy AS y
203
            FROM stu_sys_map sm
204
            WHERE sm.systems_id = :systemId
205
            AND sm.sx BETWEEN :xStart AND :xEnd
206
            AND sm.sy BETWEEN :yStart AND :yEnd',
207
            $rsm
208
        )->setParameters([
209
            'xStart' => $boundaries->getMinX(),
210
            'xEnd' => $boundaries->getMaxX(),
211
            'yStart' => $boundaries->getMinY(),
212
            'yEnd' => $boundaries->getMaxY(),
213
            'systemId' => $boundaries->getParentId()
214
        ])->getResult();
215
    }
216
217
    // TODO: Show impassable only for cartographed systems. 
218
    // Currently, it does not display any impassable areas.
219
    #[Override]
220
    public function getImpassableBorderData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
221
    {
222
        return $this->getEntityManager()->createNativeQuery(
223
            'SELECT sm.sx AS x, sm.sy AS y, TRUE AS impassable
224
            FROM stu_sys_map sm
225
            WHERE sm.systems_id = :systemId
226
            AND sm.sx BETWEEN :xStart AND :xEnd
227
            AND sm.sy BETWEEN :yStart AND :yEnd',
228
            $rsm
229
        )->setParameters([
230
            'xStart' => $boundaries->getMinX(),
231
            'xEnd' => $boundaries->getMaxX(),
232
            'yStart' => $boundaries->getMinY(),
233
            'yEnd' => $boundaries->getMaxY(),
234
            'systemId' => $boundaries->getParentId()
235
        ])->getResult();
236
    }
237
238
    #[Override]
239
    public function getCartographingData(PanelBoundaries $boundaries, ResultSetMapping $rsm, string $locations): array
240
    {
241
        return $this->getEntityManager()->createNativeQuery(
242
            'SELECT DISTINCT 
243
                sm.sx AS x, 
244
                sm.sy AS y, 
245
                CASE 
246
                    WHEN POSITION(sm.id::TEXT IN :fieldIds) > 0 THEN TRUE ELSE FALSE
247
                END AS cartographing
248
            FROM stu_sys_map sm
249
            WHERE sm.sx BETWEEN :xStart AND :xEnd
250
              AND sm.sy BETWEEN :yStart AND :yEnd
251
              AND sm.systems_id = :systemId
252
            ORDER BY cartographing DESC',
253
            $rsm
254
        )->setParameters([
255
            'xStart' => $boundaries->getMinX(),
256
            'xEnd' => $boundaries->getMaxX(),
257
            'yStart' => $boundaries->getMinY(),
258
            'yEnd' => $boundaries->getMaxY(),
259
            'systemId' => $boundaries->getParentId(),
260
            'fieldIds' => $locations
261
        ])->getResult();
262
    }
263
264
265
    #[Override]
266
    public function getAnomalyData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
267
    {
268
        return $this->getEntityManager()->createNativeQuery(
269
            'SELECT sm.sx AS x, sm.sy AS y,
270
                (SELECT array_to_string(array(SELECT a.anomaly_type_id FROM stu_anomaly a WHERE a.location_id = sm.id), \',\')) as anomalytypes
271
            FROM stu_sys_map sm
272
            WHERE sm.systems_id = :systemId
273
            AND sm.sx BETWEEN :xStart AND :xEnd
274
            AND sm.sy BETWEEN :yStart AND :yEnd',
275
            $rsm
276
        )->setParameters([
277
            'xStart' => $boundaries->getMinX(),
278
            'xEnd' => $boundaries->getMaxX(),
279
            'yStart' => $boundaries->getMinY(),
280
            'yEnd' => $boundaries->getMaxY(),
281
            'systemId' => $boundaries->getParentId()
282
        ])->getResult();
283
    }
284
285
    #[Override]
286
    public function getIgnoringSubspaceLayerData(PanelBoundaries $boundaries, int $ignoreUserId, ResultSetMapping $rsm): array
287
    {
288
        $maxAge = time() - FlightSignatureVisibilityEnum::SIG_VISIBILITY_UNCLOAKED;
289
290
        return $this->getEntityManager()->createNativeQuery(
291
            'SELECT sm.sx as x, sm.sy AS y, mft.effects as effects,
292
                (select count(distinct fs1.ship_id) from stu_flight_sig fs1
293
                where fs1.location_id = sm.id
294
                AND fs1.user_id != :ignoreUserId
295
                AND (fs1.from_direction = 1 OR fs1.to_direction = 1)
296
                AND fs1.time > :timeThreshold) as d1c,
297
                (select count(distinct fs2.ship_id) from stu_flight_sig fs2
298
                where fs2.location_id = sm.id
299
                AND fs2.user_id != :ignoreUserId
300
                AND (fs2.from_direction = 2 OR fs2.to_direction = 2)
301
                AND fs2.time > :timeThreshold) as d2c,
302
                (select count(distinct fs3.ship_id) from stu_flight_sig fs3
303
                where fs3.location_id = sm.id
304
                AND fs3.user_id != :ignoreUserId
305
                AND (fs3.from_direction = 3 OR fs3.to_direction = 3)
306
                AND fs3.time > :timeThreshold) as d3c,
307
                (select count(distinct fs4.ship_id) from stu_flight_sig fs4
308
                where fs4.location_id = sm.id
309
                AND fs4.user_id != :ignoreUserId
310
                AND (fs4.from_direction = 4 OR fs4.to_direction = 4)
311
                AND fs4.time > :timeThreshold) as d4c 
312
                FROM stu_sys_map sm
313
                JOIN stu_location l
314
                ON sm.id = l.id
315
                JOIN stu_map_ftypes mft
316
                ON l.field_id = mft.id
317
                WHERE sm.systems_id = :systemId
318
                AND sm.sx BETWEEN :xStart AND :xEnd AND sm.sy BETWEEN :yStart AND :yEnd',
319
            $rsm
320
        )->setParameters([
321
            'xStart' => $boundaries->getMinX(),
322
            'xEnd' => $boundaries->getMaxX(),
323
            'yStart' => $boundaries->getMinY(),
324
            'yEnd' => $boundaries->getMaxY(),
325
            'systemId' => $boundaries->getParentId(),
326
            'ignoreUserId' => $ignoreUserId,
327
            'timeThreshold' => $maxAge
328
        ])->getResult();
329
    }
330
331
    #[Override]
332
    public function getRandomSystemMapIdsForAstroMeasurement(int $starSystemId, int $location): array
333
    {
334
        $result = [];
335
336
        $rsm = new ResultSetMapping();
337
        $rsm->addScalarResult('id', 'id', 'integer');
338
339
        $userColonyFields = $this->getEntityManager()
340
            ->createNativeQuery(
341
                'SELECT sm.id as id
342
                FROM stu_sys_map sm
343
                WHERE sm.systems_id = :systemId
344
                AND sm.id != :location
345
                AND EXISTS (SELECT c.id
346
                            FROM stu_colonies c
347
                            WHERE c.starsystem_map_id = sm.id
348
                            AND c.user_id != :noOne)
349
                ORDER BY RANDOM()
350
                LIMIT 2',
351
                $rsm
352
            )
353
            ->setParameters([
354
                'systemId' => $starSystemId,
355
                'location'  => $location,
356
                'noOne' => UserEnum::USER_NOONE
357
            ])
358
            ->getResult();
359
360
        $result = array_merge($result, $userColonyFields);
361
362
        $otherColonyFields = $this->getEntityManager()
363
            ->createNativeQuery(
364
                'SELECT sm.id as id
365
                FROM stu_sys_map sm
366
                JOIN stu_location l
367
                ON sm.id = l.id
368
                JOIN stu_map_ftypes ft
369
                ON l.field_id = ft.id
370
                JOIN stu_colonies_classes cc
371
                ON ft.colonies_classes_id = cc.id
372
                WHERE sm.systems_id = :systemId
373
                AND ft.colonies_classes_id IS NOT NULL
374
                AND cc.type < 3
375
                AND sm.id NOT IN (:ids)
376
                ORDER BY RANDOM()
377
                LIMIT :theLimit',
378
                $rsm
379
            )
380
            ->setParameters([
381
                'systemId' => $starSystemId,
382
                'ids' => $result !== [] ? $result : [0],
383
                'theLimit' => AstronomicalMappingEnum::MEASUREMENT_COUNT - count($result)
384
            ])
385
            ->getResult();
386
387
        $result = array_merge($result, $otherColonyFields);
388
389
        if (count($result) < AstronomicalMappingEnum::MEASUREMENT_COUNT) {
390
            $otherFields = $this->getEntityManager()
391
                ->createNativeQuery(
392
                    'SELECT sm.id as id
393
                    FROM stu_sys_map sm
394
                    JOIN stu_location l
395
                    ON sm.id = l.id
396
                    JOIN stu_map_ftypes ft
397
                    ON l.field_id = ft.id
398
                    WHERE sm.systems_id = :systemId
399
                    AND ft.x_damage_system <= 10
400
                    AND ft.x_damage <= 10
401
                    ORDER BY RANDOM()
402
                    LIMIT :theLimit',
403
                    $rsm
404
                )
405
                ->setParameters([
406
                    'systemId' => $starSystemId,
407
                    'theLimit' => AstronomicalMappingEnum::MEASUREMENT_COUNT - count($result)
408
                ])
409
                ->getResult();
410
411
            $result = array_merge($result, $otherFields);
412
        }
413
414
        return array_map(fn(array $data) => $data['id'], $result);
415
    }
416
417
    #[Override]
418
    public function prototype(): StarSystemMapInterface
419
    {
420
        return new StarSystemMap();
421
    }
422
423
    #[Override]
424
    public function save(StarSystemMapInterface $starSystemMap): void
425
    {
426
        $em = $this->getEntityManager();
427
428
        $em->persist($starSystemMap);
429
    }
430
431
    #[Override]
432
    public function truncateByStarSystem(StarSystemInterface $starSystem): void
433
    {
434
        $this->getEntityManager()->createQuery(
435
            sprintf(
436
                'DELETE FROM %s sm WHERE sm.systems_id = :systemId',
437
                StarSystemMap::class
438
            )
439
        )
440
            ->setParameters(['systemId' => $starSystem->getId()])
441
            ->execute();
442
    }
443
}