Passed
Pull Request — master (#1969)
by Janko
22:34 queued 10:03
created

ShipRepository   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 382
Duplicated Lines 0 %

Test Coverage

Coverage 44.27%

Importance

Changes 10
Bugs 7 Features 0
Metric Value
eloc 280
c 10
b 7
f 0
dl 0
loc 382
ccs 85
cts 192
cp 0.4427
rs 10
wmc 18

14 Methods

Rating   Name   Duplication   Size   Complexity  
A getByLocationAndUser() 0 10 1
A delete() 0 6 1
A save() 0 6 1
A getByUserAndFleet() 0 9 1
A getPossibleFleetMembers() 0 21 1
B getFleetShipsScannerResults() 0 72 2
A getPirateFriends() 0 35 2
A getEscapePodsByCrewOwner() 0 20 1
A getByUserAndRump() 0 10 1
B getSingleSpacecraftScannerResults() 0 67 2
A getPirateTargets() 0 50 2
A getEscapePods() 0 15 1
A getAllDockedShips() 0 10 1
A getWithTradeLicensePayment() 0 21 1
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\Game\TimeConstants;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Game\TimeConstants 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...
11
use Stu\Component\Spacecraft\SpacecraftRumpEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Spacecraft\SpacecraftRumpEnum 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\SpacecraftStateEnum;
13
use Stu\Component\Spacecraft\System\SpacecraftSystemModeEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Spacecraft...pacecraftSystemModeEnum 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...
14
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
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\Module\Ship\Lib\TFleetShipItem;
17
use Stu\Module\Ship\Lib\TShipItem;
18
use Stu\Orm\Entity\Location;
19
use Stu\Orm\Entity\LocationInterface;
20
use Stu\Orm\Entity\MapInterface;
21
use Stu\Orm\Entity\PirateWrath;
22
use Stu\Orm\Entity\Ship;
23
use Stu\Orm\Entity\CrewAssignment;
24
use Stu\Orm\Entity\ShipInterface;
25
use Stu\Orm\Entity\SpacecraftRump;
26
use Stu\Orm\Entity\SpacecraftRumpInterface;
27
use Stu\Orm\Entity\Spacecraft;
28
use Stu\Orm\Entity\SpacecraftInterface;
29
use Stu\Orm\Entity\StarSystemMapInterface;
30
use Stu\Orm\Entity\Storage;
31
use Stu\Orm\Entity\User;
32
use Stu\Orm\Entity\UserInterface;
33
34
/**
35
 * @extends EntityRepository<Ship>
36
 */
37
final class ShipRepository extends EntityRepository implements ShipRepositoryInterface
38
{
39
    #[Override]
40
    public function save(ShipInterface $post): void
41
    {
42
        $em = $this->getEntityManager();
43
44
        $em->persist($post);
45
    }
46
47
    #[Override]
48
    public function delete(ShipInterface $post): void
49
    {
50
        $em = $this->getEntityManager();
51
52
        $em->remove($post);
53
    }
54
55 2
    #[Override]
56
    public function getByUserAndFleet(int $userId, ?int $fleetId): array
57
    {
58 2
        return $this->findBy(
59 2
            [
60 2
                'user_id' => $userId,
61 2
                'fleet_id' => $fleetId
62 2
            ],
63 2
            ['id' => 'asc']
64 2
        );
65
    }
66
67 1
    #[Override]
68
    public function getByLocationAndUser(LocationInterface $location, UserInterface $user): array
69
    {
70 1
        return $this->findBy([
71 1
            'user' => $user,
72 1
            'location' => $location,
73 1
        ], [
74 1
            'fleet_id' => 'desc',
75 1
            'is_fleet_leader' => 'desc',
76 1
            'id' => 'desc'
77 1
        ]);
78
    }
79
80 1
    #[Override]
81
    public function getSingleSpacecraftScannerResults(
82
        SpacecraftInterface $spacecraft,
83
        bool $showCloaked = false,
84
        MapInterface|StarSystemMapInterface|null $field = null
85
    ): array {
86
87 1
        $rsm = new ResultSetMapping();
88 1
        $rsm->addEntityResult(TShipItem::class, 's');
89 1
        TFleetShipItem::addTSpacecraftItemFields($rsm);
90
91 1
        $location = $field ?? $spacecraft->getLocation();
92
93 1
        $query = $this->getEntityManager()->createNativeQuery(
94 1
            sprintf(
95 1
                'SELECT s.id as shipid, s.fleet_id as fleetid, sp.rump_id as rumpid , ss.mode as warpstate,
96
                    twd.mode as tractorwarpstate, COALESCE(ss2.mode,0) as cloakstate, ss3.mode as shieldstate, COALESCE(ss4.status,0) as uplinkstate,
97
                    sp.type as spacecrafttype, sp.name as shipname, sp.huelle as hull, sp.max_huelle as maxhull,
98
                    sp.schilde as shield, sp.holding_web_id as webid, tw.finished_time as webfinishtime, u.id as userid, u.username,
99
                    r.category_id as rumpcategoryid, r.name as rumpname, r.role_id as rumproleid,
100
                    (SELECT count(*) > 0 FROM stu_ship_log sl WHERE sl.spacecraft_id = s.id AND sl.is_private = :false) as haslogbook,
101
                    (SELECT count(*) > 0 FROM stu_crew_assign ca WHERE ca.spacecraft_id = s.id) as hascrew
102
                FROM stu_ship s
103
                JOIN stu_spacecraft sp
104
                ON s.id = sp.id
105
                LEFT JOIN stu_spacecraft_system ss
106
                ON s.id = ss.spacecraft_id
107
                AND ss.system_type = :warpdriveType
108
                LEFT JOIN stu_spacecraft tractor
109
                ON tractor.tractored_ship_id = s.id
110
                LEFT JOIN stu_spacecraft_system twd
111
                ON tractor.id = twd.spacecraft_id
112
                AND twd.system_type = :warpdriveType
113
                LEFT JOIN stu_spacecraft_system ss2
114
                ON s.id = ss2.spacecraft_id
115
                AND ss2.system_type = :cloakType
116
                LEFT JOIN stu_spacecraft_system ss3
117
                ON s.id = ss3.spacecraft_id
118
                AND ss3.system_type = :shieldType
119
                LEFT JOIN stu_spacecraft_system ss4
120
                ON s.id = ss4.spacecraft_id
121
                AND ss4.system_type = :uplinkType
122
                JOIN stu_rump r
123
                ON sp.rump_id = r.id
124
                LEFT OUTER JOIN stu_tholian_web tw
125
                ON sp.holding_web_id = tw.id
126
                JOIN stu_user u
127
                ON sp.user_id = u.id
128
                WHERE sp.location_id = :locationId
129
                AND s.id != :ignoreId
130
                AND s.fleet_id IS NULL
131
                %s
132 1
                ORDER BY r.category_id ASC, r.role_id ASC, r.id ASC, sp.name ASC',
133 1
                $showCloaked ? '' : sprintf(' AND (sp.user_id = %d OR COALESCE(ss2.mode,0) < %d) ', $spacecraft->getUser()->getId(), SpacecraftSystemModeEnum::MODE_ON)
134 1
            ),
135 1
            $rsm
136 1
        )->setParameters([
137 1
            'locationId' => $location->getId(),
0 ignored issues
show
Bug introduced by
The method getId() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

137
            'locationId' => $location->/** @scrutinizer ignore-call */ getId(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
138 1
            'ignoreId' => $spacecraft->getId(),
139 1
            'cloakType' => SpacecraftSystemTypeEnum::SYSTEM_CLOAK->value,
140 1
            'warpdriveType' => SpacecraftSystemTypeEnum::SYSTEM_WARPDRIVE->value,
141 1
            'shieldType' => SpacecraftSystemTypeEnum::SYSTEM_SHIELDS->value,
142 1
            'uplinkType' => SpacecraftSystemTypeEnum::SYSTEM_UPLINK->value,
143 1
            'false' => false
144 1
        ]);
145
146 1
        return $query->getResult();
147
    }
148
149 1
    #[Override]
150
    public function getPossibleFleetMembers(ShipInterface $fleetLeader): iterable
151
    {
152 1
        return $this->getEntityManager()->createQuery(
153 1
            sprintf(
154 1
                'SELECT s FROM %s s
155
                JOIN %s sp
156
                WITH s.id = sp.id
157
                WHERE sp.location = :location
158
                AND s.fleet_id IS NULL
159
                AND sp.user = :user
160
                AND sp.state != :state
161 1
                ORDER BY sp.rump_id ASC, sp.name ASC',
162 1
                Ship::class,
163 1
                Spacecraft::class
164 1
            )
165 1
        )->setParameters([
166 1
            'location' => $fleetLeader->getLocation(),
167 1
            'state' => SpacecraftStateEnum::SHIP_STATE_RETROFIT,
168 1
            'user' => $fleetLeader->getUser()
169 1
        ])->getResult();
170
    }
171
172
    #[Override]
173
    public function getWithTradeLicensePayment(
174
        int $userId,
175
        int $tradePostShipId,
176
        int $commodityId,
177
        int $amount
178
    ): iterable {
179
        return $this->getEntityManager()->createQuery(
180
            sprintf(
181
                'SELECT s FROM %s s WHERE s.user_id = :userId AND s.docked_to_id = :tradePostShipId AND s.id IN (
182
                    SELECT st.spacecraft_id FROM %s st WHERE st.commodity_id = :commodityId AND st.count >= :amount
183
                )',
184
                Ship::class,
185
                Storage::class
186
            )
187
        )->setParameters([
188
            'userId' => $userId,
189
            'tradePostShipId' => $tradePostShipId,
190
            'commodityId' => $commodityId,
191
            'amount' => $amount,
192
        ])->getResult();
193
    }
194
195
    #[Override]
196
    public function getEscapePods(): array
197
    {
198
        return $this->getEntityManager()->createQuery(
199
            sprintf(
200
                'SELECT s FROM %s s
201
                LEFT JOIN %s sr
202
                WITH s.rump_id = sr.id
203
                WHERE sr.category_id = :categoryId',
204
                Ship::class,
205
                SpacecraftRump::class
206
            )
207
        )->setParameters([
208
            'categoryId' => SpacecraftRumpEnum::SHIP_CATEGORY_ESCAPE_PODS
209
        ])->getResult();
210
    }
211
212
    #[Override]
213
    public function getEscapePodsByCrewOwner(int $userId): array
214
    {
215
        return $this->getEntityManager()->createQuery(
216
            sprintf(
217
                'SELECT s FROM %s s
218
                LEFT JOIN %s sr
219
                WITH s.rump_id = sr.id
220
                LEFT JOIN %s sc
221
                WITH sc.spacecraft_id = s.id
222
                WHERE sr.category_id = :categoryId
223
                AND sc.user_id = :userId',
224
                Ship::class,
225
                SpacecraftRump::class,
226
                CrewAssignment::class
227
            )
228
        )->setParameters([
229
            'categoryId' => SpacecraftRumpEnum::SHIP_CATEGORY_ESCAPE_PODS,
230
            'userId' => $userId
231
        ])->getResult();
232
    }
233
234 1
    #[Override]
235
    public function getFleetShipsScannerResults(
236
        SpacecraftInterface $spacecraft,
237
        bool $showCloaked = false,
238
        MapInterface|StarSystemMapInterface|null $field = null
239
    ): array {
240
241 1
        $rsm = new ResultSetMapping();
242 1
        $rsm->addEntityResult(TFleetShipItem::class, 's');
243 1
        $rsm->addFieldResult('s', 'fleetname', 'fleet_name');
244 1
        $rsm->addFieldResult('s', 'isdefending', 'is_defending');
245 1
        $rsm->addFieldResult('s', 'isblocking', 'is_blocking');
246 1
        TFleetShipItem::addTSpacecraftItemFields($rsm);
247
248 1
        $location = $field ?? $spacecraft->getLocation();
249
250 1
        $query = $this->getEntityManager()->createNativeQuery(
251 1
            sprintf(
252 1
                'SELECT f.id as fleetid, f.name as fleetname, f.defended_colony_id is not null as isdefending,
253
                    f.blocked_colony_id is not null as isblocking, s.id as shipid, sp.rump_id as rumpid,
254
                    ss.mode as warpstate, twd.mode as tractorwarpstate, COALESCE(ss2.mode,0) as cloakstate, ss3.mode as shieldstate,
255
                    COALESCE(ss4.status,0) as uplinkstate, sp.type as spacecrafttype, sp.name as shipname,
256
                    sp.huelle as hull, sp.max_huelle as maxhull, sp.schilde as shield, sp.holding_web_id as webid, tw.finished_time as webfinishtime,
257
                    u.id as userid, u.username, r.category_id as rumpcategoryid, r.name as rumpname, r.role_id as rumproleid,
258
                    (SELECT count(*) > 0 FROM stu_ship_log sl WHERE sl.spacecraft_id = s.id AND sl.is_private = :false) as haslogbook,
259
                    (SELECT count(*) > 0 FROM stu_crew_assign ca WHERE ca.spacecraft_id = s.id) as hascrew
260
                FROM stu_ship s
261
                JOIN stu_spacecraft sp
262
                ON s.id = sp.id
263
                LEFT JOIN stu_spacecraft_system ss
264
                ON s.id = ss.spacecraft_id
265
                AND ss.system_type = :warpdriveType
266
                LEFT JOIN stu_spacecraft tractor
267
                ON tractor.tractored_ship_id = s.id
268
                LEFT JOIN stu_spacecraft_system twd
269
                ON tractor.id = twd.spacecraft_id
270
                AND twd.system_type = :warpdriveType
271
                LEFT JOIN stu_spacecraft_system ss2
272
                ON s.id = ss2.spacecraft_id
273
                AND ss2.system_type = :cloakType
274
                LEFT JOIN stu_spacecraft_system ss3
275
                ON s.id = ss3.spacecraft_id
276
                AND ss3.system_type = :shieldType
277
                LEFT JOIN stu_spacecraft_system ss4
278
                ON s.id = ss4.spacecraft_id
279
                AND ss4.system_type = :uplinkType
280
                JOIN stu_rump r
281
                ON sp.rump_id = r.id
282
                JOIN stu_fleets f
283
                ON s.fleet_id = f.id
284
                LEFT OUTER JOIN stu_tholian_web tw
285
                ON sp.holding_web_id = tw.id
286
                JOIN stu_user u
287
                ON sp.user_id = u.id
288
                WHERE sp.location_id = :locationId
289
                AND s.id != :ignoreId
290
                %s
291 1
                ORDER BY f.sort DESC, f.id DESC, (CASE WHEN s.is_fleet_leader THEN 0 ELSE 1 END), r.category_id ASC, r.role_id ASC, r.id ASC, sp.name ASC',
292 1
                $showCloaked ? '' : sprintf(' AND (sp.user_id = %d OR COALESCE(ss2.mode,0) < %d) ', $spacecraft->getUser()->getId(), SpacecraftSystemModeEnum::MODE_ON)
293 1
            ),
294 1
            $rsm
295 1
        )->setParameters([
296 1
            'locationId' => $location->getId(),
297 1
            'ignoreId' => $spacecraft->getId(),
298 1
            'cloakType' => SpacecraftSystemTypeEnum::SYSTEM_CLOAK->value,
299 1
            'warpdriveType' => SpacecraftSystemTypeEnum::SYSTEM_WARPDRIVE->value,
300 1
            'shieldType' => SpacecraftSystemTypeEnum::SYSTEM_SHIELDS->value,
301 1
            'uplinkType' => SpacecraftSystemTypeEnum::SYSTEM_UPLINK->value,
302 1
            'false' => false
303 1
        ]);
304
305 1
        return $query->getResult();
306
    }
307
308
    #[Override]
309
    public function getAllDockedShips(): array
310
    {
311
        return $this->getEntityManager()->createQuery(
312
            sprintf(
313
                'SELECT s FROM %s s
314
                WHERE s.docked_to_id IS NOT NULL',
315
                Ship::class
316
            )
317
        )->getResult();
318
    }
319
320
    #[Override]
321
    public function getPirateTargets(ShipInterface $ship): array
322
    {
323
        $layer = $ship->getLayer();
324
        if ($layer === null) {
325
            return [];
326
        }
327
328
        $location = $ship->getLocation();
329
        $range = $ship->getSensorRange() * 2;
330
331
        return $this->getEntityManager()->createQuery(
332
            sprintf(
333
                'SELECT s FROM %s s
334
                JOIN %s l
335
                WITH s.location = l.id
336
                JOIN %s u
337
                WITH s.user_id = u.id
338
                LEFT JOIN %s w
339
                WITH u.id = w.user_id
340
                WHERE l.layer_id = :layerId
341
                AND l.cx BETWEEN :minX AND :maxX
342
                AND l.cy BETWEEN :minY AND :maxY
343
                AND (s.fleet_id IS NULL OR s.is_fleet_leader = :true)
344
                AND u.id >= :firstUserId
345
                AND u.state >= :stateActive
346
                AND u.creation < :eightWeeksEarlier
347
                AND (u.vac_active = :false OR u.vac_request_date > :vacationThreshold)
348
                AND COALESCE(w.protection_timeout, 0) < :currentTime',
349
                Ship::class,
350
                Location::class,
351
                User::class,
352
                PirateWrath::class
353
            )
354
        )
355
            ->setParameters([
356
                'minX' => $location->getCx() - $range,
357
                'maxX' => $location->getCx() + $range,
358
                'minY' => $location->getCy() - $range,
359
                'maxY' => $location->getCy() + $range,
360
                'layerId' => $layer->getId(),
361
                'firstUserId' => UserEnum::USER_FIRST_ID,
362
                'stateActive' => UserEnum::USER_STATE_ACTIVE,
363
                'eightWeeksEarlier' => time() - TimeConstants::EIGHT_WEEKS_IN_SECONDS,
364
                'vacationThreshold' => time() - UserEnum::VACATION_DELAY_IN_SECONDS,
365
                'currentTime' => time(),
366
                'true' => true,
367
                'false' => false
368
            ])
369
            ->getResult();
370
    }
371
372
    #[Override]
373
    public function getPirateFriends(ShipInterface $ship): array
374
    {
375
        $layer = $ship->getLayer();
376
        if ($layer === null) {
377
            return [];
378
        }
379
380
        $location = $ship->getLocation();
381
        $range = $ship->getSensorRange() * 3;
382
383
        return $this->getEntityManager()->createQuery(
384
            sprintf(
385
                'SELECT s FROM %s s
386
                JOIN %s l
387
                WITH s.location_id = l.id
388
                WHERE l.layer_id = :layerId
389
                AND l.cx BETWEEN :minX AND :maxX
390
                AND l.cy BETWEEN :minY AND :maxY
391
                AND s.id != :shipId
392
                AND s.user_id = :kazonUserId',
393
                Ship::class,
394
                Location::class
395
            )
396
        )
397
            ->setParameters([
398
                'minX' => $location->getCx() - $range,
399
                'maxX' => $location->getCx() + $range,
400
                'minY' => $location->getCy() - $range,
401
                'maxY' => $location->getCy() + $range,
402
                'layerId' => $layer->getId(),
403
                'shipId' => $ship->getId(),
404
                'kazonUserId' => UserEnum::USER_NPC_KAZON
405
            ])
406
            ->getResult();
407
    }
408
409 1
    #[Override]
410
    public function getByUserAndRump(UserInterface $user, SpacecraftRumpInterface $rump): array
411
    {
412 1
        return $this->findBy([
413 1
            'user_id' => $user->getId(),
414 1
            'rump_id' => $rump->getId()
415 1
        ], [
416 1
            'location_id' => 'asc',
417 1
            'fleet_id' => 'asc',
418 1
            'is_fleet_leader' => 'desc'
419 1
        ]);
420
    }
421
}
422