Passed
Push — master ( 288b46...98b0e3 )
by Nico
31:30 queued 08:00
created

ShipLeaver::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 9
c 0
b 0
f 0
nc 1
nop 9
dl 0
loc 20
ccs 10
cts 10
cp 1
crap 1
rs 9.9666

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Ship\Lib\Crew;
6
7
use RuntimeException;
8
use Stu\Component\Ship\ShipRumpEnum;
9
use Stu\Component\Ship\ShipStateEnum;
10
use Stu\Component\Ship\System\ShipSystemManagerInterface;
11
use Stu\Module\Message\Lib\PrivateMessageFolderSpecialEnum;
12
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
13
use Stu\Module\Ship\Lib\AstroEntryLibInterface;
14
use Stu\Module\Ship\Lib\Crew\LaunchEscapePodsInterface;
15
use Stu\Module\Ship\Lib\Fleet\LeaveFleetInterface;
16
use Stu\Module\Ship\Lib\ShipWrapperInterface;
17
use Stu\Orm\Entity\ShipCrewInterface;
18
use Stu\Orm\Entity\ShipInterface;
19
use Stu\Orm\Entity\UserInterface;
20
use Stu\Orm\Repository\CrewRepositoryInterface;
21
use Stu\Orm\Repository\ShipCrewRepositoryInterface;
22
use Stu\Orm\Repository\ShipRepositoryInterface;
23
use Stu\Orm\Repository\ShipRumpRepositoryInterface;
24
25
//TODO unit tests
26
final class ShipLeaver implements ShipLeaverInterface
27
{
28
    private ShipCrewRepositoryInterface $shipCrewRepository;
29
30
    private ShipRepositoryInterface $shipRepository;
31
32
    private ShipRumpRepositoryInterface $shipRumpRepository;
33
34
    private ShipSystemManagerInterface $shipSystemManager;
35
36
    private CrewRepositoryInterface $crewRepository;
37
38
    private AstroEntryLibInterface $astroEntryLib;
39
40
    private LeaveFleetInterface $leaveFleet;
41
42
    private LaunchEscapePodsInterface $launchEscapePods;
43
44
    private PrivateMessageSenderInterface $privateMessageSender;
45
46 1
    public function __construct(
47
        ShipCrewRepositoryInterface $shipCrewRepository,
48
        ShipRepositoryInterface $shipRepository,
49
        ShipRumpRepositoryInterface $shipRumpRepository,
50
        ShipSystemManagerInterface $shipSystemManager,
51
        CrewRepositoryInterface $crewRepository,
52
        AstroEntryLibInterface $astroEntryLib,
53
        LeaveFleetInterface $leaveFleet,
54
        LaunchEscapePodsInterface $launchEscapePods,
55
        PrivateMessageSenderInterface $privateMessageSender
56
    ) {
57 1
        $this->shipCrewRepository = $shipCrewRepository;
58 1
        $this->shipRepository = $shipRepository;
59 1
        $this->shipRumpRepository = $shipRumpRepository;
60 1
        $this->shipSystemManager = $shipSystemManager;
61 1
        $this->crewRepository = $crewRepository;
62 1
        $this->astroEntryLib = $astroEntryLib;
63 1
        $this->leaveFleet = $leaveFleet;
64 1
        $this->launchEscapePods = $launchEscapePods;
65 1
        $this->privateMessageSender = $privateMessageSender;
66
    }
67
68
    public function evacuate(ShipWrapperInterface $wrapper): string
69
    {
70
        $this->shipSystemManager->deactivateAll($wrapper);
71
72
        $ship = $wrapper->get();
73
74
        $this->leaveFleet->leaveFleet($ship);
75
76
        if ($ship->getDockedShipCount() > 0) {
77
            $this->undockShips($ship);
78
        }
79
80
        if ($ship->getState() === ShipStateEnum::SHIP_STATE_ASTRO_FINALIZING) {
81
            $this->astroEntryLib->cancelAstroFinalizing($ship);
82
        }
83
84
        $ship->setAlertStateGreen();
85
        $ship->setDockedTo(null);
86
        $this->shipRepository->save($ship);
87
88
        if ($ship->getRump()->isEscapePods()) {
89
            $this->letCrewDie($ship);
90
            return _('Die Rettungskapseln wurden zerstört, die Crew ist daher verstorben!');
91
        }
92
93
        $podRump = $this->shipRumpRepository->find($ship->getUser()->getFactionId() + ShipRumpEnum::SHIP_RUMP_BASE_ID_ESCAPE_PODS);
94
95
        if ($podRump === null) {
96
            $this->letCrewDie($ship);
97
            return _('Keine Rettungskapseln vorhanden, die Crew ist daher verstorben!');
98
        }
99
100
        $this->escapeIntoPods($ship);
101
102
        return _('Die Crew hat das Schiff in den Rettungskapseln verlassen!');
103
    }
104
105
    private function escapeIntoPods(ShipInterface $ship): void
106
    {
107
        //create pods entity
108
        $pods = $this->launchEscapePods->launch($ship);
109
110
        //transfer crew into pods
111
        //TODO not all...! depends on race config
112
        $crewList = $ship->getCrewlist();
113
        foreach ($crewList as $shipCrew) {
114
            $shipCrew->setShip($pods);
115
            $shipCrew->setSlot(null);
116
            $this->shipCrewRepository->save($shipCrew);
117
        }
118
    }
119
120
    public function dumpCrewman(ShipCrewInterface $shipCrew, string $message): string
121
    {
122
        $ship = $shipCrew->getShip();
123
        if ($ship === null) {
124
            throw new RuntimeException('can only dump crewman on ship');
125
        }
126
127
        //create pods entity
128
        $pods = $this->launchEscapePods->launch($ship);
129
130
        if ($pods == null) {
131
            $crew = $shipCrew->getCrew();
132
            $this->shipCrewRepository->delete($shipCrew);
133
            $this->crewRepository->delete($crew);
134
135
            $survivalMessage = _('Der Crewman wurde exekutiert!');
136
        } else {
137
138
            //transfer crewman into pods
139
            $shipCrew->setShip($pods);
140
            $shipCrew->setShipId($pods->getId());
141
            $ship->getCrewlist()->removeElement($shipCrew);
142
            $this->shipCrewRepository->save($shipCrew);
143
144
            $survivalMessage = _('Der Crewman hat das Schiff in einer Rettungskapsel verlassen!');
145
        }
146
147
        $this->sendPmToOwner(
148
            $ship->getUser(),
149
            $shipCrew->getUser(),
150
            $message,
151
            $survivalMessage
152
        );
153
154
        return $survivalMessage;
155
    }
156
157
    private function sendPmToOwner(
158
        UserInterface $sender,
159
        UserInterface $owner,
160
        string $message,
161
        string $survivalMessage
162
    ): void {
163
        $this->privateMessageSender->send(
164
            $sender->getId(),
165
            $owner->getId(),
166
            sprintf(
167
                "%s\n%s",
168
                $message,
169
                $survivalMessage
170
            ),
171
            PrivateMessageFolderSpecialEnum::PM_SPECIAL_SYSTEM
172
        );
173
    }
174
175
    private function letCrewDie(ShipInterface $ship): void
176
    {
177
        $crewArray = [];
178
        foreach ($ship->getCrewlist() as $shipCrew) {
179
            $crewArray[] = $shipCrew->getCrew();
180
        }
181
182
        $this->shipCrewRepository->truncateByShip($ship->getId());
183
184
        foreach ($crewArray as $crew) {
185
            $this->crewRepository->delete($crew);
186
        }
187
    }
188
189
    private function undockShips(ShipInterface $ship): void
190
    {
191
        foreach ($ship->getDockedShips() as $dockedShip) {
192
            $dockedShip->setDockedTo(null);
193
            $this->shipRepository->save($dockedShip);
194
        }
195
    }
196
}
197