Passed
Push — master ( 6d626d...5de675 )
by Janko
09:20
created

StarSystemMapRepository::getLssBlockadeLocations()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 28
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 25
nc 1
nop 1
dl 0
loc 28
ccs 16
cts 16
cp 1
crap 1
rs 9.52
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\FieldTypeEffectEnum;
15
use Stu\Lib\Map\VisualPanel\PanelBoundaries;
16
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...
17
use Stu\Orm\Entity\StarSystem;
18
use Stu\Orm\Entity\StarSystemMap;
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
    ): ?StarSystemMap {
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 4
    #[Override]
91
    public function getMapLayerData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
92
    {
93 4
        return $this->getEntityManager()->createNativeQuery(
94 4
            '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 4
                AND sm.systems_id = :systemId',
101 4
            $rsm
102 4
        )->setParameters([
103 4
            'xStart' => $boundaries->getMinX(),
104 4
            'xEnd' => $boundaries->getMaxX(),
105 4
            'yStart' => $boundaries->getMinY(),
106 4
            'yEnd' => $boundaries->getMaxY(),
107 4
            'systemId' => $boundaries->getParentId()
108 4
        ])->getResult();
109
    }
110
111 4
    #[Override]
112
    public function getSpacecraftCountLayerData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
113
    {
114 4
        return $this->getEntityManager()->createNativeQuery(
115 4
            '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 4
            GROUP BY sm.id, sm.sy, sm.sx, l.field_id',
138 4
            $rsm
139 4
        )->setParameters([
140 4
            'xStart' => $boundaries->getMinX(),
141 4
            'xEnd' => $boundaries->getMaxX(),
142 4
            'yStart' => $boundaries->getMinY(),
143 4
            'yEnd' => $boundaries->getMaxY(),
144 4
            'systemId' => $boundaries->getParentId(),
145 4
            'cloakSystemId' => SpacecraftSystemTypeEnum::CLOAK->value
146 4
        ])->getResult();
147
    }
148
149 4
    #[Override]
150
    public function getColonyShieldData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
151
    {
152 4
        return $this->getEntityManager()->createNativeQuery(
153 4
            'SELECT sm.sx as x, sm.sy AS y,
154
            (SELECT COUNT(*) > 0
155
                FROM stu_colony 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 4
            AND sm.sx BETWEEN :xStart AND :xEnd AND sm.sy BETWEEN :yStart AND :yEnd',
167 4
            $rsm
168 4
        )->setParameters([
169 4
            'xStart' => $boundaries->getMinX(),
170 4
            'xEnd' => $boundaries->getMaxX(),
171 4
            'yStart' => $boundaries->getMinY(),
172 4
            'yEnd' => $boundaries->getMaxY(),
173 4
            'systemId' => $boundaries->getParentId(),
174 4
            'active' => 1,
175 4
            'shieldBuilding' => BuildingFunctionEnum::SHIELD_GENERATOR
176 4
        ])->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
                    (SELECT mft.complementary_color FROM stu_map_ftypes mft JOIN stu_location l on l.id = sm.id where mft.id = l.field_id) AS complementary_color
225
            FROM stu_sys_map sm
226
            WHERE sm.systems_id = :systemId
227
            AND sm.sx BETWEEN :xStart AND :xEnd
228
            AND sm.sy BETWEEN :yStart AND :yEnd',
229
            $rsm
230
        )->setParameters([
231
            'xStart' => $boundaries->getMinX(),
232
            'xEnd' => $boundaries->getMaxX(),
233
            'yStart' => $boundaries->getMinY(),
234
            'yEnd' => $boundaries->getMaxY(),
235
            'systemId' => $boundaries->getParentId()
236
        ])->getResult();
237
    }
238
239
    #[Override]
240
    public function getCartographingData(PanelBoundaries $boundaries, ResultSetMapping $rsm, array $locations): array
241
    {
242
        return $this->getEntityManager()->createNativeQuery(
243
            'SELECT DISTINCT 
244
                sm.sx AS x, 
245
                sm.sy AS y, 
246
                CASE 
247
                    WHEN sm.id IN (:fieldIds) THEN TRUE ELSE FALSE
248
                END AS cartographing,
249
                    (SELECT mft.complementary_color FROM stu_map_ftypes mft JOIN stu_location l on l.id = sm.id where mft.id = l.field_id) AS complementary_color
250
            FROM stu_sys_map sm
251
            WHERE sm.sx BETWEEN :xStart AND :xEnd
252
            AND sm.sy BETWEEN :yStart AND :yEnd
253
            AND sm.systems_id = :systemId
254
            ORDER BY cartographing DESC',
255
            $rsm
256
        )->setParameters([
257
            'xStart' => $boundaries->getMinX(),
258
            'xEnd' => $boundaries->getMaxX(),
259
            'yStart' => $boundaries->getMinY(),
260
            'yEnd' => $boundaries->getMaxY(),
261
            'systemId' => $boundaries->getParentId(),
262
            'fieldIds' => $locations
263
        ])->getResult();
264
    }
265
266
267
    #[Override]
268
    public function getAnomalyData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
269
    {
270
        return $this->getEntityManager()->createNativeQuery(
271
            'SELECT sm.sx AS x, sm.sy AS y,
272
                (SELECT array_to_string(array(SELECT a.anomaly_type_id FROM stu_anomaly a WHERE a.location_id = sm.id), \',\')) as anomalytypes
273
            FROM stu_sys_map sm
274
            WHERE sm.systems_id = :systemId
275
            AND sm.sx BETWEEN :xStart AND :xEnd
276
            AND sm.sy BETWEEN :yStart AND :yEnd',
277
            $rsm
278
        )->setParameters([
279
            'xStart' => $boundaries->getMinX(),
280
            'xEnd' => $boundaries->getMaxX(),
281
            'yStart' => $boundaries->getMinY(),
282
            'yEnd' => $boundaries->getMaxY(),
283
            'systemId' => $boundaries->getParentId()
284
        ])->getResult();
285
    }
286
287 4
    #[Override]
288
    public function getLssBlockadeLocations(PanelBoundaries $boundaries): array
289
    {
290 4
        $rsm = new ResultSetMapping();
291 4
        $rsm->addScalarResult('sx', 'x', 'integer');
292 4
        $rsm->addScalarResult('sy', 'y', 'integer');
293 4
        $rsm->addScalarResult('effects', 'effects', 'string');
294
295 4
        return $this->getEntityManager()->createNativeQuery(
296 4
            'WITH bbox AS (
297
                SELECT id, sx, sy
298
                FROM stu_sys_map
299
                WHERE systems_id = :systemId
300
                AND sx BETWEEN :xStart AND :xEnd
301
                AND sy BETWEEN :yStart AND :yEnd
302
            )
303
            SELECT sm.sx, sm.sy, mft.effects
304
            FROM bbox sm
305
            JOIN stu_location l ON sm.id = l.id
306 4
            JOIN stu_map_ftypes mft ON mft.id   = l.field_id',
307 4
            $rsm
308 4
        )->setParameters([
309 4
            'xStart' => $boundaries->getMinX(),
310 4
            'xEnd' => $boundaries->getMaxX(),
311 4
            'yStart' => $boundaries->getMinY(),
312 4
            'yEnd' => $boundaries->getMaxY(),
313 4
            'systemId' => $boundaries->getParentId()
314 4
        ])->getResult();
315
    }
316
317
    #[Override]
318
    public function getIgnoringSubspaceLayerData(PanelBoundaries $boundaries, int $ignoreUserId, ResultSetMapping $rsm): array
319
    {
320
        $maxAge = time() - FlightSignatureVisibilityEnum::SIG_VISIBILITY_UNCLOAKED;
321
322
        return $this->getEntityManager()->createNativeQuery(
323
            'SELECT sm.sx as x, sm.sy AS y, mft.effects as effects,
324
                (select count(distinct fs1.ship_id) from stu_flight_sig fs1
325
                where fs1.location_id = sm.id
326
                AND fs1.user_id != :ignoreUserId
327
                AND (fs1.from_direction = 1 OR fs1.to_direction = 1)
328
                AND fs1.time > :timeThreshold) as d1c,
329
                (select count(distinct fs2.ship_id) from stu_flight_sig fs2
330
                where fs2.location_id = sm.id
331
                AND fs2.user_id != :ignoreUserId
332
                AND (fs2.from_direction = 2 OR fs2.to_direction = 2)
333
                AND fs2.time > :timeThreshold) as d2c,
334
                (select count(distinct fs3.ship_id) from stu_flight_sig fs3
335
                where fs3.location_id = sm.id
336
                AND fs3.user_id != :ignoreUserId
337
                AND (fs3.from_direction = 3 OR fs3.to_direction = 3)
338
                AND fs3.time > :timeThreshold) as d3c,
339
                (select count(distinct fs4.ship_id) from stu_flight_sig fs4
340
                where fs4.location_id = sm.id
341
                AND fs4.user_id != :ignoreUserId
342
                AND (fs4.from_direction = 4 OR fs4.to_direction = 4)
343
                AND fs4.time > :timeThreshold) as d4c 
344
                FROM stu_sys_map sm
345
                JOIN stu_location l
346
                ON sm.id = l.id
347
                JOIN stu_map_ftypes mft
348
                ON l.field_id = mft.id
349
                WHERE sm.systems_id = :systemId
350
                AND sm.sx BETWEEN :xStart AND :xEnd AND sm.sy BETWEEN :yStart AND :yEnd',
351
            $rsm
352
        )->setParameters([
353
            'xStart' => $boundaries->getMinX(),
354
            'xEnd' => $boundaries->getMaxX(),
355
            'yStart' => $boundaries->getMinY(),
356
            'yEnd' => $boundaries->getMaxY(),
357
            'systemId' => $boundaries->getParentId(),
358
            'ignoreUserId' => $ignoreUserId,
359
            'timeThreshold' => $maxAge
360
        ])->getResult();
361
    }
362
363
    #[Override]
364
    public function getRandomSystemMapIdsForAstroMeasurement(int $starSystemId, int $location): array
365
    {
366
        $result = [];
367
368
        $rsm = new ResultSetMapping();
369
        $rsm->addScalarResult('id', 'id', 'integer');
370
371
        $userColonyFields = $this->getEntityManager()
372
            ->createNativeQuery(
373
                'SELECT sm.id as id
374
                FROM stu_sys_map sm
375
                WHERE sm.systems_id = :systemId
376
                AND sm.id != :location
377
                AND EXISTS (SELECT c.id
378
                            FROM stu_colony c
379
                            WHERE c.starsystem_map_id = sm.id
380
                            AND c.user_id != :noOne)
381
                ORDER BY RANDOM()
382
                LIMIT 2',
383
                $rsm
384
            )
385
            ->setParameters([
386
                'systemId' => $starSystemId,
387
                'location'  => $location,
388
                'noOne' => UserEnum::USER_NOONE
389
            ])
390
            ->getResult();
391
392
        $result = array_merge($result, $userColonyFields);
393
394
        $otherColonyFields = $this->getEntityManager()
395
            ->createNativeQuery(
396
                'SELECT sm.id as id
397
                FROM stu_sys_map sm
398
                JOIN stu_location l
399
                ON sm.id = l.id
400
                JOIN stu_map_ftypes ft
401
                ON l.field_id = ft.id
402
                JOIN stu_colonies_classes cc
403
                ON ft.colonies_classes_id = cc.id
404
                WHERE sm.systems_id = :systemId
405
                AND ft.colonies_classes_id IS NOT NULL
406
                AND cc.type < 3
407
                AND sm.id NOT IN (:ids)
408
                ORDER BY RANDOM()
409
                LIMIT :theLimit',
410
                $rsm
411
            )
412
            ->setParameters([
413
                'systemId' => $starSystemId,
414
                'ids' => $result !== [] ? $result : [0],
415
                'theLimit' => AstronomicalMappingEnum::MEASUREMENT_COUNT - count($result)
416
            ])
417
            ->getResult();
418
419
        $result = array_merge($result, $otherColonyFields);
420
421
        if (count($result) < AstronomicalMappingEnum::MEASUREMENT_COUNT) {
422
            $otherFields = $this->getEntityManager()
423
                ->createNativeQuery(
424
                    'SELECT sm.id as id
425
                    FROM stu_sys_map sm
426
                    JOIN stu_location l
427
                    ON sm.id = l.id
428
                    JOIN stu_map_ftypes ft
429
                    ON l.field_id = ft.id
430
                    WHERE sm.systems_id = :systemId
431
                    AND ft.x_damage_system <= 10
432
                    AND ft.x_damage <= 10
433
                    ORDER BY RANDOM()
434
                    LIMIT :theLimit',
435
                    $rsm
436
                )
437
                ->setParameters([
438
                    'systemId' => $starSystemId,
439
                    'theLimit' => AstronomicalMappingEnum::MEASUREMENT_COUNT - count($result)
440
                ])
441
                ->getResult();
442
443
            $result = array_merge($result, $otherFields);
444
        }
445
446
        return array_map(fn(array $data) => $data['id'], $result);
447
    }
448
449
    #[Override]
450
    public function prototype(): StarSystemMap
451
    {
452
        return new StarSystemMap();
453
    }
454
455
    #[Override]
456
    public function save(StarSystemMap $starSystemMap): void
457
    {
458
        $em = $this->getEntityManager();
459
460
        $em->persist($starSystemMap);
461
    }
462
463
    #[Override]
464
    public function truncateByStarSystem(StarSystem $starSystem): void
465
    {
466
        $this->getEntityManager()->createQuery(
467
            sprintf(
468
                'DELETE FROM %s sm WHERE sm.systems_id = :systemId',
469
                StarSystemMap::class
470
            )
471
        )
472
            ->setParameters(['systemId' => $starSystem->getId()])
473
            ->execute();
474
    }
475
}
476