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

MapRepository::save()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
ccs 0
cts 3
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 RuntimeException;
11
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...
12
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
13
use Stu\Lib\Map\VisualPanel\PanelBoundaries;
14
use Stu\Module\PlayerSetting\Lib\UserSettingEnum;
15
use Stu\Module\Starmap\Lib\ExploreableStarMap;
16
use Stu\Orm\Entity\LayerInterface;
17
use Stu\Orm\Entity\Location;
18
use Stu\Orm\Entity\Map;
19
use Stu\Orm\Entity\MapInterface;
20
use Stu\Orm\Entity\UserInterface;
21
22
/**
23
 * @extends EntityRepository<Map>
24
 */
25
final class MapRepository extends EntityRepository implements MapRepositoryInterface
26
{
27
    #[Override]
28
    public function getAmountByLayer(LayerInterface $layer): int
29
    {
30
        return $this->count([
31
            'layer_id' => $layer->getId()
32
        ]);
33
    }
34
35
    #[Override]
36
    public function getAllOrdered(int $layerId): array
37
    {
38
        return $this->getEntityManager()
39
            ->createQuery(
40
                sprintf(
41
                    'SELECT m FROM %s m
42
                    JOIN %s l
43
                    WITH m.id = l.id
44
                    WHERE l.layer_id = :layerId
45
                    ORDER BY l.cy, l.cx',
46
                    Map::class,
47
                    Location::class
48
                )
49
            )
50
            ->setParameters([
51
                'layerId' => $layerId
52
            ])
53
            ->getResult();
54
    }
55
56
    #[Override]
57
    public function getAllWithSystem(int $layerId): array
58
    {
59
        return $this->getEntityManager()
60
            ->createQuery(
61
                sprintf(
62
                    'SELECT m FROM %s m INDEX BY m.id
63
                    JOIN %s l
64
                    WITH m.id = l.id
65
                    WHERE l.layer_id = :layerId
66
                    AND m.systems_id IS NOT null',
67
                    Map::class,
68
                    Location::class
69
                )
70
            )
71
            ->setParameters([
72
                'layerId' => $layerId
73
            ])
74
            ->getResult();
75
    }
76
77
    #[Override]
78
    public function getAllWithoutSystem(int $layerId): array
79
    {
80
        return $this->getEntityManager()
81
            ->createQuery(
82
                sprintf(
83
                    'SELECT m FROM %s m INDEX BY m.id
84
                    JOIN %s l
85
                    WITH m.id = l.id
86
                    WHERE l.layer_id = :layerId
87
                    AND m.systems_id IS null',
88
                    Map::class,
89
                    Location::class
90
                )
91
            )
92
            ->setParameters([
93
                'layerId' => $layerId
94
            ])
95
            ->getResult();
96
    }
97
98 1
    #[Override]
99
    public function getByCoordinates(?LayerInterface $layer, int $cx, int $cy): ?MapInterface
100
    {
101 1
        if ($layer === null) {
102
            return null;
103
        }
104
105 1
        return $this->findOneBy([
106 1
            'layer_id' => $layer->getId(),
107 1
            'cx' => $cx,
108 1
            'cy' => $cy
109 1
        ]);
110
    }
111
112
    #[Override]
113
    public function getByBoundaries(PanelBoundaries $boundaries): array
114
    {
115
        return $this->getByCoordinateRange(
116
            $boundaries->getParentId(),
117
            $boundaries->getMinX(),
118
            $boundaries->getMaxX(),
119
            $boundaries->getMinY(),
120
            $boundaries->getMaxY()
121
        );
122
    }
123
124
    #[Override]
125
    public function getByCoordinateRange(
126
        int $layerId,
127
        int $startCx,
128
        int $endCx,
129
        int $startCy,
130
        int $endCy,
131
        bool $sortAscending = true
132
    ): array {
133
        return $this->getEntityManager()
134
            ->createQuery(
135
                sprintf(
136
                    'SELECT m FROM %s m
137
                    JOIN %s l
138
                    WITH m.id = l.id
139
                    WHERE l.cx BETWEEN :startCx AND :endCx
140
                    AND l.cy BETWEEN :startCy AND :endCy
141
                    AND l.layer_id = :layerId
142
                    ORDER BY l.cy %3$s, l.cx %3$s',
143
                    Map::class,
144
                    Location::class,
145
                    $sortAscending ? 'ASC' : 'DESC'
146
                )
147
            )
148
            ->setParameters([
149
                'layerId' => $layerId,
150
                'startCx' => $startCx,
151
                'endCx' => $endCx,
152
                'startCy' => $startCy,
153
                'endCy' => $endCy
154
            ])
155
            ->getResult();
156
    }
157
158
    #[Override]
159
    public function save(MapInterface $map): void
160
    {
161
        $em = $this->getEntityManager();
162
163
        $em->persist($map);
164
    }
165
166 1
    #[Override]
167
    public function getNormalBorderData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
168
    {
169 1
        return $this->getEntityManager()->createNativeQuery(
170 1
            'SELECT l.cx AS x, l.cy AS y
171
            FROM stu_map m
172
            JOIN stu_location l
173
            ON m.id = l.id
174
            WHERE l.cx BETWEEN :xStart AND :xEnd
175
            AND l.cy BETWEEN :yStart AND :yEnd
176 1
            AND l.layer_id = :layerId',
177 1
            $rsm
178 1
        )->setParameters([
179 1
            'xStart' => $boundaries->getMinX(),
180 1
            'xEnd' => $boundaries->getMaxX(),
181 1
            'yStart' => $boundaries->getMinY(),
182 1
            'yEnd' => $boundaries->getMaxY(),
183 1
            'layerId' => $boundaries->getParentId()
184 1
        ])->getResult();
185
    }
186
187
    #[Override]
188
    public function getCartographingData(PanelBoundaries $boundaries, ResultSetMapping $rsm, string $locations): array
189
    {
190
191
        return $this->getEntityManager()->createNativeQuery(
192
            'SELECT DISTINCT 
193
                l.cx AS x, 
194
                l.cy AS y, 
195
                CASE 
196
                    WHEN POSITION(l.id::TEXT IN :fieldIds) > 0 THEN TRUE ELSE FALSE
197
                END AS cartographing
198
            FROM stu_location l
199
            WHERE l.cx BETWEEN :xStart AND :xEnd
200
              AND l.cy BETWEEN :yStart AND :yEnd
201
              AND l.layer_id = :layerId
202
            ORDER BY cartographing DESC',
203
            $rsm
204
        )->setParameters([
205
            'xStart' => $boundaries->getMinX(),
206
            'xEnd' => $boundaries->getMaxX(),
207
            'yStart' => $boundaries->getMinY(),
208
            'yEnd' => $boundaries->getMaxY(),
209
            'layerId' => $boundaries->getParentId(),
210
            'fieldIds' => $locations
211
        ])->getResult();
212
    }
213
214
215
    #[Override]
216
    public function getRegionBorderData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
217
    {
218
        return $this->getEntityManager()->createNativeQuery(
219
            'SELECT l.cx AS x, l.cy AS y,
220
                (SELECT al.rgb_code FROM stu_alliances al
221
                    JOIN stu_user u ON al.id = u.allys_id
222
                    JOIN stu_spacecraft sc ON u.id = sc.user_id
223
                    JOIN stu_station s ON sc.id = s.id
224
                    JOIN stu_map ma ON ma.influence_area_id = s.influence_area_id
225
                    WHERE ma.id = m.id AND ma.bordertype_id IS NULL AND ma.admin_region_id IS NULL)
226
                            AS allycolor,
227
                (SELECT COALESCE(us.value, \'\') FROM stu_user u
228
                    LEFT JOIN stu_user_setting us ON u.id = us.user_id
229
                    JOIN stu_spacecraft sc ON u.id = sc.user_id
230
                    JOIN stu_station s ON sc.id = s.id
231
                    JOIN stu_map mu ON mu.influence_area_id = s.influence_area_id
232
                    WHERE us.setting = :rgbCodeSetting
233
                    AND mu.id = m.id AND mu.bordertype_id IS NULL AND mu.admin_region_id IS NULL)
234
                        as usercolor,
235
                (SELECT mbt.color FROM stu_map_bordertypes mbt
236
                    JOIN stu_map mb ON mb.bordertype_id = mbt.id
237
                    WHERE mb.id = m.id AND mb.bordertype_id IS NOT NULL)
238
                        AS factioncolor
239
            FROM stu_map m
240
            JOIN stu_location l
241
            ON m.id = l.id
242
            WHERE l.cx BETWEEN :xStart AND :xEnd
243
            AND l.cy BETWEEN :yStart AND :yEnd
244
            AND l.layer_id = :layerId',
245
            $rsm
246
        )->setParameters([
247
            'xStart' => $boundaries->getMinX(),
248
            'xEnd' => $boundaries->getMaxX(),
249
            'yStart' => $boundaries->getMinY(),
250
            'yEnd' => $boundaries->getMaxY(),
251
            'layerId' => $boundaries->getParentId(),
252
            'rgbCodeSetting' => UserSettingEnum::RGB_CODE->value
253
        ])->getResult();
254
    }
255
256
    #[Override]
257
    public function getImpassableBorderData(PanelBoundaries $boundaries, Userinterface $user, ResultSetMapping $rsm): array
258
    {
259
        return $this->getEntityManager()->createNativeQuery(
260
            'SELECT DISTINCT 
261
                l.cx AS x, 
262
                l.cy AS y,
263
                CASE 
264
                    WHEN mf.passable = FALSE 
265
                         AND EXISTS (
266
                            SELECT 1 
267
                            FROM stu_database_user du
268
                            JOIN stu_database_entrys de ON du.database_id = de.id
269
                            WHERE du.user_id = :userId
270
                            AND de.id = r.database_id
271
                         ) 
272
                    THEN FALSE
273
                    ELSE TRUE
274
                END AS impassable
275
            FROM stu_location l
276
            LEFT JOIN stu_map_ftypes mf ON l.field_id = mf.id
277
            LEFT JOIN stu_map m ON l.id = m.id
278
            LEFT JOIN stu_map_regions r ON m.region_id = r.id
279
            WHERE l.cx BETWEEN :xStart AND :xEnd
280
              AND l.cy BETWEEN :yStart AND :yEnd
281
              AND l.layer_id = :layerId',
282
            $rsm
283
        )->setParameters([
284
            'xStart' => $boundaries->getMinX(),
285
            'xEnd' => $boundaries->getMaxX(),
286
            'yStart' => $boundaries->getMinY(),
287
            'yEnd' => $boundaries->getMaxY(),
288
            'layerId' => $boundaries->getParentId(),
289
            'userId' => $user->getId()
290
        ])->getResult();
291
    }
292
293
294
    #[Override]
295
    public function getAnomalyData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
296
    {
297
        return $this->getEntityManager()->createNativeQuery(
298
            'SELECT l.cx AS x, l.cy AS y,
299
                (SELECT array_to_string(array(SELECT a.anomaly_type_id FROM stu_anomaly a WHERE a.location_id = m.id), \',\')) as anomalytypes
300
            FROM stu_map m
301
            JOIN stu_location l
302
            ON m.id = l.id
303
            WHERE l.cx BETWEEN :xStart AND :xEnd
304
            AND l.cy BETWEEN :yStart AND :yEnd
305
            AND l.layer_id = :layerId',
306
            $rsm
307
        )->setParameters([
308
            'xStart' => $boundaries->getMinX(),
309
            'xEnd' => $boundaries->getMaxX(),
310
            'yStart' => $boundaries->getMinY(),
311
            'yEnd' => $boundaries->getMaxY(),
312
            'layerId' => $boundaries->getParentId(),
313
        ])->getResult();
314
    }
315
316 1
    #[Override]
317
    public function getSpacecraftCountLayerData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
318
    {
319 1
        return $this->getEntityManager()->createNativeQuery(
320 1
            'SELECT l.cx as x, l.cy AS y, mft.effects as effects,
321
                (SELECT count(DISTINCT b.id) FROM stu_spacecraft b
322
                    JOIN stu_location l2
323
                    ON b.location_id = l2.id
324
                    WHERE l2.layer_id = l.layer_id 
325
                    AND l2.cx = l.cx
326
                    AND l2.cy = l.cy
327
                    AND NOT EXISTS (SELECT ss.id
328
                                        FROM stu_spacecraft_system ss
329
                                        WHERE b.id = ss.spacecraft_id
330
                                        AND ss.system_type = :cloakSystemId
331
                                        AND ss.mode > 1)) AS spacecraftcount,
332
                (SELECT count(DISTINCT c.id) FROM stu_spacecraft c
333
                    JOIN stu_location l2
334
                    ON c.location_id = l2.id
335
                    WHERE l2.layer_id = l.layer_id 
336
                    AND l2.cx = l.cx
337
                    AND l2.cy = l.cy
338
                    AND EXISTS (SELECT ss2.id
339
                                        FROM stu_spacecraft_system ss2
340
                                        WHERE c.id = ss2.spacecraft_id
341
                                        AND ss2.system_type = :cloakSystemId
342
                                        AND ss2.mode > 1)) AS cloakcount
343
            FROM stu_map m
344
            JOIN stu_location l
345
            ON m.id = l.id
346
            JOIN stu_map_ftypes mft
347
            ON l.field_id = mft.id
348
            WHERE l.cx BETWEEN :xStart AND :xEnd
349
            AND l.cy BETWEEN :yStart AND :yEnd
350 1
            AND l.layer_id = :layerId',
351 1
            $rsm
352 1
        )->setParameters([
353 1
            'xStart' => $boundaries->getMinX(),
354 1
            'xEnd' => $boundaries->getMaxX(),
355 1
            'yStart' => $boundaries->getMinY(),
356 1
            'yEnd' => $boundaries->getMaxY(),
357 1
            'layerId' => $boundaries->getParentId(),
358 1
            'cloakSystemId' => SpacecraftSystemTypeEnum::CLOAK->value
359 1
        ])->getResult();
360
    }
361
362
363 1
    #[Override]
364
    public function getMapLayerData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
365
    {
366 1
        return $this->getEntityManager()->createNativeQuery(
367 1
            'SELECT l.cx as x, l.cy AS y, ft.type
368
                FROM stu_map m
369
                JOIN stu_location l
370
                ON m.id = l.id
371
                JOIN stu_map_ftypes ft ON ft.id = l.field_id
372
                WHERE l.cx BETWEEN :xStart AND :xEnd AND l.cy BETWEEN :yStart AND :yEnd
373 1
                AND l.layer_id = :layerId',
374 1
            $rsm
375 1
        )->setParameters([
376 1
            'xStart' => $boundaries->getMinX(),
377 1
            'xEnd' => $boundaries->getMaxX(),
378 1
            'yStart' => $boundaries->getMinY(),
379 1
            'yEnd' => $boundaries->getMaxY(),
380 1
            'layerId' => $boundaries->getParentId(),
381 1
        ])->getResult();
382
    }
383
384
    #[Override]
385
    public function getUserSpacecraftCountLayerData(PanelBoundaries $boundaries, int $userId, ResultSetMapping $rsm): array
386
    {
387
        return $this->getEntityManager()->createNativeQuery(
388
            'SELECT l.cx as x, l.cy as y, mft.effects as effects,
389
            (SELECT count(distinct s.id)
390
                FROM stu_spacecraft s
391
                JOIN stu_location spl
392
                ON s.location_id = spl.id
393
                WHERE spl.cx = l.cx
394
                AND spl.cy = l.cy
395
                AND spl.layer_id = l.layer_id
396
                AND s.user_id = :userId) as spacecraftcount
397
            FROM stu_map m
398
            JOIN stu_location l
399
            ON m.id = l.id
400
            JOIN stu_map_ftypes mft
401
            ON l.field_id = mft.id
402
            WHERE l.cx BETWEEN :xStart AND :xEnd
403
            AND l.cy BETWEEN :yStart AND :yEnd
404
            AND l.layer_id = :layerId',
405
            $rsm
406
        )->setParameters([
407
            'xStart' => $boundaries->getMinX(),
408
            'xEnd' => $boundaries->getMaxX(),
409
            'yStart' => $boundaries->getMinY(),
410
            'yEnd' => $boundaries->getMaxY(),
411
            'layerId' => $boundaries->getParentId(),
412
            'userId' => $userId
413
        ])->getResult();
414
    }
415
416
    #[Override]
417
    public function getAllianceSpacecraftCountLayerData(PanelBoundaries $boundaries, int $allianceId, ResultSetMapping $rsm): array
418
    {
419
        return $this->getEntityManager()->createNativeQuery(
420
            'SELECT l.cx as x, l.cy as y, mft.effects as effects,
421
             (SELECT count(distinct s.id)
422
                    FROM stu_spacecraft s
423
                    JOIN stu_location spl
424
                    ON s.location_id = spl.id
425
                    JOIN stu_user u
426
                    ON s.user_id = u.id
427
                    WHERE spl.cx = l.cx
428
                    AND spl.cy = l.cy
429
                    AND spl.layer_id = l.layer_id
430
                    AND u.allys_id = :allyId) as spacecraftcount
431
            FROM stu_map m
432
            JOIN stu_location l
433
            ON m.id = l.id
434
            JOIN stu_map_ftypes mft
435
            ON l.field_id = mft.id
436
            WHERE l.cx BETWEEN :xStart AND :xEnd
437
            AND l.cy BETWEEN :yStart AND :yEnd
438
            AND l.layer_id = :layerId',
439
            $rsm
440
        )->setParameters([
441
            'xStart' => $boundaries->getMinX(),
442
            'xEnd' => $boundaries->getMaxX(),
443
            'yStart' => $boundaries->getMinY(),
444
            'yEnd' => $boundaries->getMaxY(),
445
            'layerId' => $boundaries->getParentId(),
446
            'allyId' => $allianceId
447
        ])->getResult();
448
    }
449
450
    #[Override]
451
    public function getSpacecraftCountLayerDataForSpacecraft(PanelBoundaries $boundaries, int $spacecraftId, ResultSetMapping $rsm): array
452
    {
453
        return $this->getEntityManager()->createNativeQuery(
454
            'SELECT l.cx as x, l.cy as y, mft.effects as effects,
455
            (SELECT count(distinct s.id)
456
                FROM stu_spacecraft s
457
                JOIN stu_location spl
458
                ON s.location_id = spl.id
459
                WHERE spl.cx = l.cx
460
                AND spl.cy = l.cy
461
                AND spl.layer_id = l.layer_id
462
                AND s.id = :spacecraftId) as spacecraftcount
463
            FROM stu_map m
464
            JOIN stu_location l
465
            ON m.id = l.id
466
            JOIN stu_map_ftypes mft
467
            ON l.field_id = mft.id
468
            WHERE l.cx BETWEEN :xStart AND :xEnd
469
            AND l.cy BETWEEN :yStart AND :yEnd
470
            AND l.layer_id = :layerId',
471
            $rsm
472
        )->setParameters([
473
            'xStart' => $boundaries->getMinX(),
474
            'xEnd' => $boundaries->getMaxX(),
475
            'yStart' => $boundaries->getMinY(),
476
            'yEnd' => $boundaries->getMaxY(),
477
            'layerId' => $boundaries->getParentId(),
478
            'spacecraftId' => $spacecraftId
479
        ])->getResult();
480
    }
481
482 3
    #[Override]
483
    public function getExplored(int $userId, int $layerId, int $startX, int $endX, int $cy): array
484
    {
485 3
        $rsm = new ResultSetMapping();
486 3
        $rsm->addEntityResult(ExploreableStarMap::class, 'm');
487 3
        $rsm->addFieldResult('m', 'id', 'id');
488 3
        $rsm->addFieldResult('m', 'cx', 'cx');
489 3
        $rsm->addFieldResult('m', 'cy', 'cy');
490 3
        $rsm->addFieldResult('m', 'field_id', 'field_id');
491 3
        $rsm->addFieldResult('m', 'bordertype_id', 'bordertype_id');
492 3
        $rsm->addFieldResult('m', 'user_id', 'user_id');
493 3
        $rsm->addFieldResult('m', 'mapped', 'mapped');
494 3
        $rsm->addFieldResult('m', 'system_name', 'system_name');
495 3
        $rsm->addFieldResult('m', 'influence_area_id', 'influence_area_id');
496 3
        $rsm->addFieldResult('m', 'region_id', 'region_id');
497 3
        $rsm->addFieldResult('m', 'tradepost_id', 'tradepost_id');
498 3
        $rsm->addFieldResult('m', 'region_description', 'region_description');
499 3
        $rsm->addFieldResult('m', 'layer_id', 'layer_id');
500
501 3
        return $this->getEntityManager()
502 3
            ->createNativeQuery(
503 3
                'SELECT m.id, l.cx, l.cy, l.field_id, m.systems_id, m.bordertype_id, um.user_id,
504
                    dbu.database_id as mapped, m.influence_area_id as influence_area_id, m.admin_region_id as region_id,
505
                    sys.name as system_name, l.layer_id,
506
                    (SELECT tp.id FROM stu_spacecraft s JOIN stu_trade_posts tp ON s.id = tp.station_id WHERE s.location_id = m.id) as tradepost_id,
507
                    (SELECT mr.description FROM stu_map_regions mr JOIN stu_database_user dbu on dbu.user_id = :userId and mr.database_id = dbu.database_id WHERE m.region_id = mr.id) as region_description
508
                FROM stu_map m
509
                JOIN stu_location l
510
                ON m.id = l.id
511
                LEFT JOIN stu_user_map um
512
                    ON um.cy = l.cy AND um.cx = l.cx AND um.user_id = :userId AND um.layer_id = l.layer_id
513
                LEFT JOIN stu_systems sys
514
                    ON m.systems_id = sys.id
515
                LEFT JOIN stu_database_user dbu
516
                    ON dbu.user_id = :userId
517
                    AND sys.database_id = dbu.database_id
518
                WHERE l.cx BETWEEN :startX AND :endX
519
                AND l.cy = :cy
520
                AND l.layer_id = :layerId
521 3
                ORDER BY l.cx ASC',
522 3
                $rsm
523 3
            )
524 3
            ->setParameters([
525 3
                'layerId' => $layerId,
526 3
                'userId' => $userId,
527 3
                'startX' => $startX,
528 3
                'endX' => $endX,
529 3
                'cy' => $cy
530 3
            ])
531 3
            ->getResult();
532
    }
533
534
    #[Override]
535
    public function getWithEmptySystem(LayerInterface $layer): array
536
    {
537
        return $this->getEntityManager()
538
            ->createQuery(
539
                sprintf(
540
                    'SELECT m from %s m
541
                    JOIN %s l
542
                    WITH m.id = l.id
543
                    WHERE m.system_type_id IS NOT NULL
544
                    AND m.systems_id IS NULL
545
                    AND l.layer = :layer',
546
                    Map::class,
547
                    Location::class
548
                )
549
            )
550
            ->setParameters([
551
                'layer' => $layer
552
            ])
553
            ->getResult();
554
    }
555
556
    #[Override]
557
    public function getRandomMapIdsForAstroMeasurement(int $regionId, int $maxPercentage, int $location): array
558
    {
559
        $rsm = new ResultSetMapping();
560
        $rsm->addScalarResult('id', 'id', 'integer');
561
562
        $mapIdResultSet = $this->getEntityManager()
563
            ->createNativeQuery(
564
                'SELECT m.id FROM stu_map m
565
                JOIN stu_location l
566
                ON m.id = l.id
567
                JOIN stu_map_ftypes mf
568
                ON l.field_id = mf.id
569
                WHERE m.region_id = :regionId
570
                AND mf.passable = :true
571
                AND m.id != :loc
572
                ORDER BY RANDOM()',
573
                $rsm
574
            )
575
            ->setParameters([
576
                'regionId' => $regionId,
577
                'loc' => $location,
578
                'true' => true
579
            ])
580
            ->getResult();
581
582
        $amount = (int)ceil(count($mapIdResultSet) * $maxPercentage / 100);
583
        $subset = array_slice($mapIdResultSet, 0, $amount);
584
585
        return array_map(fn(array $data) => $data['id'], $subset);
586
    }
587
588
    #[Override]
589
    public function getRandomPassableUnoccupiedWithoutDamage(LayerInterface $layer, bool $isAtBorder = false): MapInterface
590
    {
591
        $rsm = new ResultSetMapping();
592
        $rsm->addScalarResult('id', 'id', 'integer');
593
594
        $borderCriteria = $isAtBorder ?
595
            sprintf(
596
                'AND (l.cx in (1, %d) OR l.cy in (1, %d))',
597
                $layer->getWidth(),
598
                $layer->getHeight()
599
            ) : '';
600
601
        $randomMapId =  (int)$this->getEntityManager()
602
            ->createNativeQuery(
603
                sprintf(
604
                    'SELECT m.id
605
                    FROM stu_map m
606
                    JOIN stu_location l
607
                    ON m.id = l.id
608
                    JOIN stu_map_ftypes mft
609
                    ON l.field_id = mft.id
610
                    WHERE NOT EXISTS (SELECT s.id FROM stu_spacecraft s WHERE s.location_id = m.id)
611
                    AND l.layer_id = :layerId
612
                    AND mft.x_damage = 0
613
                    AND mft.passable = :true
614
                    %s
615
                    ORDER BY RANDOM()
616
                    LIMIT 1',
617
                    $borderCriteria
618
                ),
619
                $rsm
620
            )
621
            ->setParameters([
622
                'layerId' => $layer->getId(),
623
                'true' => true
624
            ])
625
            ->getSingleScalarResult();
626
627
        $map = $this->find($randomMapId);
628
        if ($map === null) {
629
            throw new RuntimeException('this should not happen');
630
        }
631
632
        return $map;
633
    }
634
635
    #[Override]
636
    public function getIgnoringSubspaceLayerData(PanelBoundaries $boundaries, int $ignoreUserId, ResultSetMapping $rsm): array
637
    {
638
        $maxAge = time() - FlightSignatureVisibilityEnum::SIG_VISIBILITY_UNCLOAKED;
639
640
        return $this->getEntityManager()->createNativeQuery(
641
            'SELECT l.cx AS x, l.cy AS y, mft.effects as effects,
642
                (SELECT count(distinct fs1.ship_id) from stu_flight_sig fs1
643
                WHERE fs1.location_id = l.id
644
                AND fs1.user_id != :ignoreUserId
645
                AND (fs1.from_direction = 1 OR fs1.to_direction = 1)
646
                AND fs1.time > :timeThreshold) as d1c,
647
                (SELECT count(distinct fs2.ship_id) from stu_flight_sig fs2
648
                WHERE fs2.location_id = l.id
649
                AND fs2.user_id !=:ignoreUserId
650
                AND (fs2.from_direction = 2 OR fs2.to_direction = 2)
651
                AND fs2.time > :timeThreshold) as d2c,
652
                (SELECT count(distinct fs3.ship_id) from stu_flight_sig fs3
653
                WHERE fs3.location_id = l.id
654
                AND fs3.user_id != :ignoreUserId
655
                AND (fs3.from_direction = 3 OR fs3.to_direction = 3)
656
                AND fs3.time > :timeThreshold) as d3c,
657
                (SELECT count(distinct fs4.ship_id) from stu_flight_sig fs4
658
                WHERE fs4.location_id = l.id
659
                AND fs4.user_id != :ignoreUserId
660
                AND (fs4.from_direction = 4 OR fs4.to_direction = 4)
661
                AND fs4.time > :timeThreshold) as d4c 
662
                FROM stu_location l
663
                JOIN stu_map m
664
                ON l.id = m.id
665
                JOIN stu_map_ftypes mft
666
                ON l.field_id = mft.id
667
                WHERE l.cx BETWEEN :xStart AND :xEnd
668
                AND l.cy BETWEEN :yStart AND :yEnd
669
                AND l.layer_id = :layerId',
670
            $rsm
671
        )->setParameters([
672
            'xStart' => $boundaries->getMinX(),
673
            'xEnd' => $boundaries->getMaxX(),
674
            'yStart' => $boundaries->getMinY(),
675
            'yEnd' => $boundaries->getMaxY(),
676
            'layerId' => $boundaries->getParentId(),
677
            'ignoreUserId' => $ignoreUserId,
678
            'timeThreshold' => $maxAge
679
        ])->getResult();
680
    }
681
682
    #[Override]
683
    public function getSubspaceLayerData(PanelBoundaries $boundaries, ResultSetMapping $rsm): array
684
    {
685
        return $this->getEntityManager()->createNativeQuery(
686
            'SELECT l.cx as x, l.cy as y, mft.effects as effects,
687
            (SELECT count(distinct fs1.ship_id) from stu_flight_sig fs1
688
                WHERE fs1.location_id = l.id
689
                AND (fs1.from_direction = 1 OR fs1.to_direction = 1)) as d1c,
690
            (SELECT count(distinct fs2.ship_id) from stu_flight_sig fs2
691
                WHERE fs2.location_id = l.id
692
                AND (fs2.from_direction = 2 OR fs2.to_direction = 2)) as d2c,
693
            (SELECT count(distinct fs3.ship_id) from stu_flight_sig fs3
694
                WHERE fs3.location_id = l.id
695
                AND (fs3.from_direction = 3 OR fs3.to_direction = 3)) as d3c,
696
            (SELECT count(distinct fs4.ship_id) from stu_flight_sig fs4
697
                WHERE fs4.location_id = l.id
698
                AND (fs4.from_direction = 4 OR fs4.to_direction = 4)) as d4c 
699
            FROM stu_location l
700
            JOIN stu_map_ftypes mft
701
            ON l.field_id = mft.id
702
            WHERE l.cx BETWEEN :xStart AND :xEnd
703
            AND l.cy BETWEEN :yStart AND :yEnd
704
            AND l.layer_id = :layerId',
705
            $rsm
706
        )->setParameters([
707
            'xStart' => $boundaries->getMinX(),
708
            'xEnd' => $boundaries->getMaxX(),
709
            'yStart' => $boundaries->getMinY(),
710
            'yEnd' => $boundaries->getMaxY(),
711
            'layerId' => $boundaries->getParentId()
712
        ])->getResult();
713
    }
714
715
    #[Override]
716
    public function getUserSubspaceLayerData(PanelBoundaries $boundaries, int $userId, ResultSetMapping $rsm): array
717
    {
718
        return $this->getEntityManager()->createNativeQuery(
719
            'SELECT l.cx as x, l.cy as y, mft.effects as effects,
720
            (SELECT count(distinct fs1.ship_id) from stu_flight_sig fs1
721
                WHERE fs1.location_id = l.id
722
                AND fs1.user_id = :userId
723
                AND (fs1.from_direction = 1 OR fs1.to_direction = 1)) as d1c,
724
            (SELECT count(distinct fs2.ship_id) from stu_flight_sig fs2
725
                WHERE fs2.location_id = l.id
726
                AND fs2.user_id = :userId
727
                AND (fs2.from_direction = 2 OR fs2.to_direction = 2)) as d2c,
728
            (SELECT count(distinct fs3.ship_id) from stu_flight_sig fs3
729
                WHERE fs3.location_id = l.id
730
                AND fs3.user_id = :userId
731
                AND (fs3.from_direction = 3 OR fs3.to_direction = 3)) as d3c,
732
            (SELECT count(distinct fs4.ship_id) from stu_flight_sig fs4
733
                WHERE fs4.location_id = l.id
734
                AND fs4.user_id = :userId
735
                AND (fs4.from_direction = 4 OR fs4.to_direction = 4)) as d4c 
736
            FROM stu_location l
737
            JOIN stu_map_ftypes mft
738
            ON l.field_id = mft.id
739
            WHERE l.cx BETWEEN :xStart AND :xEnd
740
            AND l.cy BETWEEN :yStart AND :yEnd
741
            AND l.layer_id = :layerId',
742
            $rsm
743
        )->setParameters([
744
            'xStart' => $boundaries->getMinX(),
745
            'xEnd' => $boundaries->getMaxX(),
746
            'yStart' => $boundaries->getMinY(),
747
            'yEnd' => $boundaries->getMaxY(),
748
            'layerId' => $boundaries->getParentId(),
749
            'userId' => $userId
750
        ])->getResult();
751
    }
752
753
    #[Override]
754
    public function getShipSubspaceLayerData(PanelBoundaries $boundaries, int $shipId, ResultSetMapping $rsm): array
755
    {
756
        return $this->getEntityManager()->createNativeQuery(
757
            'SELECT l.cx as x, l.cy as y, mft.effects as effects,
758
            (SELECT count(distinct fs1.ship_id) from stu_flight_sig fs1
759
                WHERE fs1.location_id = l.id
760
                AND fs1.ship_id = :shipId
761
                AND (fs1.from_direction = 1 OR fs1.to_direction = 1)) as d1c,
762
            (SELECT count(distinct fs2.ship_id) from stu_flight_sig fs2
763
                WHERE fs2.location_id = l.id
764
                AND fs2.ship_id = :shipId
765
                AND (fs2.from_direction = 2 OR fs2.to_direction = 2)) as d2c,
766
            (SELECT count(distinct fs3.ship_id) from stu_flight_sig fs3
767
                WHERE fs3.location_id = l.id
768
                AND fs3.ship_id = :shipId
769
                AND (fs3.from_direction = 3 OR fs3.to_direction = 3)) as d3c,
770
            (SELECT count(distinct fs4.ship_id) from stu_flight_sig fs4
771
                WHERE fs4.location_id = l.id
772
                AND fs4.ship_id = :shipId
773
                AND (fs4.from_direction = 4 OR fs4.to_direction = 4)) as d4c 
774
            FROM stu_location l
775
            JOIN stu_map_ftypes mft
776
            ON l.field_id = mft.id
777
            WHERE l.cx BETWEEN :xStart AND :xEnd
778
            AND l.cy BETWEEN :yStart AND :yEnd
779
            AND l.layer_id = :layerId',
780
            $rsm
781
        )->setParameters([
782
            'xStart' => $boundaries->getMinX(),
783
            'xEnd' => $boundaries->getMaxX(),
784
            'yStart' => $boundaries->getMinY(),
785
            'yEnd' => $boundaries->getMaxY(),
786
            'layerId' => $boundaries->getParentId(),
787
            'shipId' => $shipId
788
        ])->getResult();
789
    }
790
791
    #[Override]
792
    public function getAllianceSubspaceLayerData(PanelBoundaries $boundaries, int $allianceId, ResultSetMapping $rsm): array
793
    {
794
        return $this->getEntityManager()->createNativeQuery(
795
            'SELECT l.id, l.cx as x, l.cy as y, mft.effects as effects,
796
            (SELECT count(distinct fs1.ship_id) from stu_flight_sig fs1
797
                JOIN stu_user u1 ON fs1.user_id = u1.id
798
                WHERE fs1.location_id = l.id
799
                AND u1.allys_id = :allyId
800
                AND (fs1.from_direction = 1 OR fs1.to_direction = 1)) as d1c,
801
            (SELECT count(distinct fs2.ship_id) from stu_flight_sig fs2
802
                JOIN stu_user u2 ON fs2.user_id = u2.id
803
                WHERE fs2.location_id = l.id
804
                AND u2.allys_id = :allyId
805
                AND (fs2.from_direction = 2 OR fs2.to_direction = 2)) as d2c,
806
            (SELECT count(distinct fs3.ship_id) from stu_flight_sig fs3
807
                JOIN stu_user u3 ON fs3.user_id = u3.id
808
                WHERE fs3.location_id = l.id
809
                AND u3.allys_id = :allyId
810
                AND (fs3.from_direction = 3 OR fs3.to_direction = 3)) as d3c,
811
            (SELECT count(distinct fs4.ship_id) from stu_flight_sig fs4
812
                JOIN stu_user u4 ON fs4.user_id = u4.id
813
                WHERE fs4.location_id = l.id
814
                AND u4.allys_id = :allyId
815
                AND (fs4.from_direction = 4 OR fs4.to_direction = 4)) as d4c 
816
            FROM stu_location l
817
            JOIN stu_map_ftypes mft
818
            ON l.field_id = mft.id
819
            WHERE l.cx BETWEEN :xStart AND :xEnd
820
            AND l.cy BETWEEN :yStart AND :yEnd
821
            AND l.layer_id = :layerId',
822
            $rsm
823
        )->setParameters([
824
            'xStart' => $boundaries->getMinX(),
825
            'xEnd' => $boundaries->getMaxX(),
826
            'yStart' => $boundaries->getMinY(),
827
            'yEnd' => $boundaries->getMaxY(),
828
            'layerId' => $boundaries->getParentId(),
829
            'allyId' => $allianceId
830
        ])->getResult();
831
    }
832
833 1
    public function getUniqueInfluenceAreaIds(): array
834
    {
835 1
        $rsm = new ResultSetMapping();
836 1
        $rsm->addScalarResult('influence_area_id', 'influence_area_id', 'integer');
837
838 1
        $query = $this->getEntityManager()->createNativeQuery(
839 1
            'SELECT DISTINCT influence_area_id
840
             FROM stu_map
841
             WHERE influence_area_id IS NOT NULL
842 1
             ORDER BY influence_area_id ASC',
843 1
            $rsm
844 1
        );
845
846 1
        return array_map('intval', array_column($query->getResult(), 'influence_area_id'));
847
    }
848
}