Passed
Push — dev ( 45bf8d...5b8f46 )
by Janko
10:07
created

StarSystemMapRepository::getAnomalyData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 16
nc 1
nop 2
dl 0
loc 18
ccs 0
cts 12
cp 0
crap 2
rs 9.7333
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
            FROM stu_sys_map sm
131
            WHERE sm.sx BETWEEN :xStart AND :xEnd AND sm.sy BETWEEN :yStart AND :yEnd
132
            AND sm.systems_id = :systemId
133 3
            GROUP BY sm.id, sm.sy, sm.sx',
134 3
            $rsm
135 3
        )->setParameters([
136 3
            'xStart' => $boundaries->getMinX(),
137 3
            'xEnd' => $boundaries->getMaxX(),
138 3
            'yStart' => $boundaries->getMinY(),
139 3
            'yEnd' => $boundaries->getMaxY(),
140 3
            'systemId' => $boundaries->getParentId(),
141 3
            'cloakSystemId' => SpacecraftSystemTypeEnum::CLOAK->value
142 3
        ])->getResult();
143
    }
144
145 3
    #[Override]
146
    public function getColonyShieldData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
147
    {
148 3
        return $this->getEntityManager()->createNativeQuery(
149 3
            'SELECT sm.sx as x, sm.sy AS y,
150
            (SELECT COUNT(*) > 0
151
                FROM stu_colonies col
152
                JOIN stu_colonies_fielddata cfd
153
                ON col.id = cfd.colonies_id
154
                WHERE sm.id = col.starsystem_map_id
155
                AND cfd.aktiv = :active
156
                AND cfd.buildings_id IN (
157
                    SELECT bf.buildings_id
158
                    FROM stu_buildings_functions bf
159
                    WHERE bf.function = :shieldBuilding)) AS shieldstate
160
            FROM stu_sys_map sm
161
            WHERE sm.systems_id = :systemId
162 3
            AND sm.sx BETWEEN :xStart AND :xEnd AND sm.sy BETWEEN :yStart AND :yEnd',
163 3
            $rsm
164 3
        )->setParameters([
165 3
            'xStart' => $boundaries->getMinX(),
166 3
            'xEnd' => $boundaries->getMaxX(),
167 3
            'yStart' => $boundaries->getMinY(),
168 3
            'yEnd' => $boundaries->getMaxY(),
169 3
            'systemId' => $boundaries->getParentId(),
170 3
            'active' => 1,
171 3
            'shieldBuilding' => BuildingFunctionEnum::BUILDING_FUNCTION_SHIELD_GENERATOR
172 3
        ])->getResult();
173
    }
174
175
176
    #[Override]
177
    public function getBorderData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
178
    {
179
        return $this->getEntityManager()->createNativeQuery(
180
            'SELECT sm.sx AS x, sm.sy AS y
181
            FROM stu_sys_map sm
182
            WHERE sm.systems_id = :systemId
183
            AND sm.sx BETWEEN :xStart AND :xEnd
184
            AND sm.sy BETWEEN :yStart AND :yEnd',
185
            $rsm
186
        )->setParameters([
187
            'xStart' => $boundaries->getMinX(),
188
            'xEnd' => $boundaries->getMaxX(),
189
            'yStart' => $boundaries->getMinY(),
190
            'yEnd' => $boundaries->getMaxY(),
191
            'systemId' => $boundaries->getParentId()
192
        ])->getResult();
193
    }
194
195
    #[Override]
196
    public function getAnomalyData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
197
    {
198
        return $this->getEntityManager()->createNativeQuery(
199
            'SELECT sm.sx AS x, sm.sy AS y,
200
                (SELECT array_to_string(array(SELECT a.anomaly_type_id FROM stu_anomaly a WHERE a.location_id = sm.id), \',\')) as anomalytypes
201
            FROM stu_sys_map sm
202
            WHERE sm.systems_id = :systemId
203
            AND sm.sx BETWEEN :xStart AND :xEnd
204
            AND sm.sy BETWEEN :yStart AND :yEnd',
205
            $rsm
206
        )->setParameters([
207
            'xStart' => $boundaries->getMinX(),
208
            'xEnd' => $boundaries->getMaxX(),
209
            'yStart' => $boundaries->getMinY(),
210
            'yEnd' => $boundaries->getMaxY(),
211
            'systemId' => $boundaries->getParentId()
212
        ])->getResult();
213
    }
214
215
    #[Override]
216
    public function getIgnoringSubspaceLayerData(PanelBoundaries $boundaries, int $ignoreId, ResultSetMapping $rsm): array
217
    {
218
        $maxAge = time() - FlightSignatureVisibilityEnum::SIG_VISIBILITY_UNCLOAKED;
219
220
        return $this->getEntityManager()->createNativeQuery(
221
            sprintf(
222
                'SELECT sm.sx as x, sm.sy AS y,
223
                (select count(distinct fs1.ship_id) from stu_flight_sig fs1
224
                where fs1.location_id = sm.id
225
                AND fs1.user_id != %1$d
226
                AND (fs1.from_direction = 1 OR fs1.to_direction = 1)
227
                AND fs1.time > %2$d) as d1c,
228
                (select count(distinct fs2.ship_id) from stu_flight_sig fs2
229
                where fs2.location_id = sm.id
230
                AND fs2.user_id != %1$d
231
                AND (fs2.from_direction = 2 OR fs2.to_direction = 2)
232
                AND fs2.time > %2$d) as d2c,
233
                (select count(distinct fs3.ship_id) from stu_flight_sig fs3
234
                where fs3.location_id = sm.id
235
                AND fs3.user_id != %1$d
236
                AND (fs3.from_direction = 3 OR fs3.to_direction = 3)
237
                AND fs3.time > %2$d) as d3c,
238
                (select count(distinct fs4.ship_id) from stu_flight_sig fs4
239
                where fs4.location_id = sm.id
240
                AND fs4.user_id != %1$d
241
                AND (fs4.from_direction = 4 OR fs4.to_direction = 4)
242
                AND fs4.time > %2$d) as d4c 
243
                FROM stu_sys_map sm
244
                WHERE sm.systems_id = :systemId
245
                AND sm.sx BETWEEN :xStart AND :xEnd AND sm.sy BETWEEN :yStart AND :yEnd',
246
                $ignoreId,
247
                $maxAge
248
            ),
249
            $rsm
250
        )->setParameters([
251
            'xStart' => $boundaries->getMinX(),
252
            'xEnd' => $boundaries->getMaxX(),
253
            'yStart' => $boundaries->getMinY(),
254
            'yEnd' => $boundaries->getMaxY(),
255
            'systemId' => $boundaries->getParentId()
256
        ])->getResult();
257
    }
258
259
    #[Override]
260
    public function getRandomSystemMapIdsForAstroMeasurement(int $starSystemId, int $location): array
261
    {
262
        $result = [];
263
264
        $rsm = new ResultSetMapping();
265
        $rsm->addScalarResult('id', 'id', 'integer');
266
267
        $userColonyFields = $this->getEntityManager()
268
            ->createNativeQuery(
269
                'SELECT sm.id as id
270
                FROM stu_sys_map sm
271
                WHERE sm.systems_id = :systemId
272
                AND sm.id != :location
273
                AND EXISTS (SELECT c.id
274
                            FROM stu_colonies c
275
                            WHERE c.starsystem_map_id = sm.id
276
                            AND c.user_id != :noOne)
277
                ORDER BY RANDOM()
278
                LIMIT 2',
279
                $rsm
280
            )
281
            ->setParameters([
282
                'systemId' => $starSystemId,
283
                'location'  => $location,
284
                'noOne' => UserEnum::USER_NOONE
285
            ])
286
            ->getResult();
287
288
        $result = array_merge($result, $userColonyFields);
289
290
        $otherColonyFields = $this->getEntityManager()
291
            ->createNativeQuery(
292
                'SELECT sm.id as id
293
                FROM stu_sys_map sm
294
                JOIN stu_location l
295
                ON sm.id = l.id
296
                JOIN stu_map_ftypes ft
297
                ON l.field_id = ft.id
298
                JOIN stu_colonies_classes cc
299
                ON ft.colonies_classes_id = cc.id
300
                WHERE sm.systems_id = :systemId
301
                AND ft.colonies_classes_id IS NOT NULL
302
                AND cc.type < 3
303
                AND sm.id NOT IN (:ids)
304
                ORDER BY RANDOM()
305
                LIMIT :theLimit',
306
                $rsm
307
            )
308
            ->setParameters([
309
                'systemId' => $starSystemId,
310
                'ids' => $result !== [] ? $result : [0],
311
                'theLimit' => AstronomicalMappingEnum::MEASUREMENT_COUNT - count($result)
312
            ])
313
            ->getResult();
314
315
        $result = array_merge($result, $otherColonyFields);
316
317
        if (count($result) < AstronomicalMappingEnum::MEASUREMENT_COUNT) {
318
            $otherFields = $this->getEntityManager()
319
                ->createNativeQuery(
320
                    'SELECT sm.id as id
321
                    FROM stu_sys_map sm
322
                    JOIN stu_location l
323
                    ON sm.id = l.id
324
                    JOIN stu_map_ftypes ft
325
                    ON l.field_id = ft.id
326
                    WHERE sm.systems_id = :systemId
327
                    AND ft.x_damage_system <= 10
328
                    AND ft.x_damage <= 10
329
                    ORDER BY RANDOM()
330
                    LIMIT :theLimit',
331
                    $rsm
332
                )
333
                ->setParameters([
334
                    'systemId' => $starSystemId,
335
                    'theLimit' => AstronomicalMappingEnum::MEASUREMENT_COUNT - count($result)
336
                ])
337
                ->getResult();
338
339
            $result = array_merge($result, $otherFields);
340
        }
341
342
        return array_map(fn(array $data) => $data['id'], $result);
343
    }
344
345
    #[Override]
346
    public function prototype(): StarSystemMapInterface
347
    {
348
        return new StarSystemMap();
349
    }
350
351
    #[Override]
352
    public function save(StarSystemMapInterface $starSystemMap): void
353
    {
354
        $em = $this->getEntityManager();
355
356
        $em->persist($starSystemMap);
357
    }
358
359
    #[Override]
360
    public function truncateByStarSystem(StarSystemInterface $starSystem): void
361
    {
362
        $this->getEntityManager()->createQuery(
363
            sprintf(
364
                'DELETE FROM %s sm WHERE sm.systems_id = :systemId',
365
                StarSystemMap::class
366
            )
367
        )
368
            ->setParameters(['systemId' => $starSystem->getId()])
369
            ->execute();
370
    }
371
}
372