Passed
Pull Request — master (#1821)
by Nico
52:02 queued 25:23
created

Transfer::handle()   B

Complexity

Conditions 10
Paths 7

Size

Total Lines 91
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 110

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 10
eloc 60
c 2
b 1
f 0
nc 7
nop 1
dl 0
loc 91
ccs 0
cts 65
cp 0
crap 110
rs 7.006

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Ship\Action\Transfer;
6
7
use request;
8
use RuntimeException;
9
use Stu\Component\Player\Relation\PlayerRelationDeterminatorInterface;
10
use Stu\Exception\SanityCheckException;
11
use Stu\Lib\Information\InformationWrapper;
12
use Stu\Lib\Transfer\Strategy\TransferStrategyInterface;
13
use Stu\Lib\Transfer\TransferInformation;
14
use Stu\Lib\Transfer\TransferTargetLoaderInterface;
15
use Stu\Lib\Transfer\TransferTypeEnum;
16
use Stu\Module\Colony\View\ShowColony\ShowColony;
17
use Stu\Module\Control\ActionControllerInterface;
18
use Stu\Module\Control\GameControllerInterface;
19
use Stu\Module\Logging\LoggerUtilFactoryInterface;
20
use Stu\Module\Logging\LoggerUtilInterface;
21
use Stu\Module\Message\Lib\PrivateMessageFolderSpecialEnum;
22
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
23
use Stu\Module\Ship\Lib\Interaction\InteractionChecker;
24
use Stu\Module\Ship\Lib\ShipLoaderInterface;
25
use Stu\Module\Ship\View\ShowShip\ShowShip;
26
use Stu\Orm\Entity\ShipInterface;
27
28
final class Transfer implements ActionControllerInterface
29
{
30
    public const ACTION_IDENTIFIER = 'B_TRANSFER';
31
32
    private ShipLoaderInterface $shipLoader;
33
34
    private TransferTargetLoaderInterface $transferTargetLoader;
35
36
    private PlayerRelationDeterminatorInterface $playerRelationDeterminator;
37
38
    private PrivateMessageSenderInterface $privateMessageSender;
39
40
    private LoggerUtilInterface $logger;
41
42
    /** @var array<TransferStrategyInterface> */
43
    private array $transferStrategies;
44
45
    /** @param array<TransferStrategyInterface> $transferStrategies */
46
47
    public function __construct(
48
        ShipLoaderInterface $shipLoader,
49
        TransferTargetLoaderInterface $transferTargetLoader,
50
        PlayerRelationDeterminatorInterface $playerRelationDeterminator,
51
        PrivateMessageSenderInterface $privateMessageSender,
52
        LoggerUtilFactoryInterface $loggerUtilFactory,
53
        array $transferStrategies
54
    ) {
55
        $this->shipLoader = $shipLoader;
56
        $this->transferTargetLoader = $transferTargetLoader;
57
        $this->playerRelationDeterminator = $playerRelationDeterminator;
58
        $this->privateMessageSender = $privateMessageSender;
59
        $this->transferStrategies = $transferStrategies;
60
61
        $this->logger = $loggerUtilFactory->getLoggerUtil();
62
        //$this->logger->init('TRANSFER', LoggerEnum::LEVEL_ERROR);
63
    }
64
65
    public function handle(GameControllerInterface $game): void
66
    {
67
        $game->setView(ShowShip::VIEW_IDENTIFIER);
68
69
        $userId = $game->getUser()->getId();
70
71
        $shipId = request::postIntFatal('id');
72
        $targetId = request::postIntFatal('target');
73
        $isUnload = request::postIntFatal('is_unload') === 1;
74
        $isColonyTarget = request::postIntFatal('is_colony') === 1;
75
        $transferType = TransferTypeEnum::from(request::postIntFatal('transfer_type'));
76
77
        $wrapper = $this->shipLoader->getWrapperByIdAndUser(
78
            $shipId,
79
            $userId
80
        );
81
82
        $ship = $wrapper->get();
83
84
        $this->logger->log('T1');
85
86
        //bad request
87
        if (!$ship->hasEnoughCrew($game)) {
88
            $this->logger->log('T2');
89
            return;
90
        }
91
92
        $this->logger->log('T3');
93
        $target = $this->transferTargetLoader->loadTarget($targetId, $isColonyTarget);
94
95
        $transferInformation = new TransferInformation(
96
            $transferType,
97
            $ship,
98
            $target,
99
            $isUnload,
100
            $this->playerRelationDeterminator->isFriend($target->getUser(), $ship->getUser())
101
        );
102
103
        $this->logger->log('TS1');
104
        $this->sanityCheck($transferInformation);
105
        $this->logger->log('TS2');
106
107
        if (!InteractionChecker::canInteractWith($ship, $target, $game, true)) {
108
            $this->logger->log('T4');
109
            return;
110
        }
111
112
        if ($ship->getCloakState()) {
113
            $game->addInformation(_("Die Tarnung ist aktiviert"));
114
            $this->logger->log('T5');
115
            return;
116
        }
117
118
        if ($ship->isWarped()) {
119
            $game->addInformation("Schiff befindet sich im Warp");
120
            $this->logger->log('T7');
121
            return;
122
        }
123
        if ($ship->getShieldState()) {
124
            $game->addInformation(_("Die Schilde sind aktiviert"));
125
            $this->logger->log('T8');
126
            return;
127
        }
128
129
        if ($target instanceof ShipInterface && $target->isWarped()) {
130
            $game->addInformationf('Die %s befindet sich im Warp', $target->getName());
131
            $this->logger->log('T9');
132
            return;
133
        }
134
        $this->logger->log('T10');
135
136
        $strategy = $this->getTransferStrategy($transferType);
137
138
        $informations = new InformationWrapper();
139
140
        $strategy->transfer($isUnload, $wrapper, $target, $informations);
141
142
        $this->privateMessageSender->send(
143
            $ship->getUser()->getId(),
144
            $target->getUser()->getId(),
145
            $informations->getInformationsAsString(),
146
            PrivateMessageFolderSpecialEnum::PM_SPECIAL_TRADE,
147
            sprintf(
148
                '%s.php?%s=1&id=%d',
149
                $target instanceof ShipInterface ? 'ship' : 'colony',
150
                $target instanceof ShipInterface ? ShowShip::VIEW_IDENTIFIER : ShowColony::VIEW_IDENTIFIER,
151
                $target->getId()
152
            )
153
        );
154
155
        $game->addInformationWrapper($informations);
156
    }
157
158
    private function sanityCheck(TransferInformation $transferInformation): void
159
    {
160
        switch ($transferInformation->getTransferType()) {
161
            case TransferTypeEnum::COMMODITIES:
162
                if ($transferInformation->isCommodityTransferPossible(false)) {
163
                    return;
164
                }
165
                break;
166
            case TransferTypeEnum::CREW:
167
                if ($transferInformation->isCrewTransferPossible(false)) {
168
                    return;
169
                }
170
                break;
171
            case TransferTypeEnum::TORPEDOS:
172
                if ($transferInformation->isTorpedoTransferPossible(false)) {
173
                    return;
174
                }
175
                break;
176
        }
177
178
        throw new SanityCheckException(sprintf(
179
            'userId %d tried to transfer %s %s targetId %d (%s), but it is not possible',
180
            $transferInformation->getSource()->getUser()->getId(),
181
            $transferInformation->getTransferType()->getGoodName(),
182
            $transferInformation->isUnload() ? 'to' : 'from',
183
            $transferInformation->getTarget()->getId(),
184
            $transferInformation->isColonyTarget() ? 'colony' : 'ship'
185
        ));
186
    }
187
188
    private function getTransferStrategy(TransferTypeEnum $transferType): TransferStrategyInterface
189
    {
190
        if (!array_key_exists($transferType->value, $this->transferStrategies)) {
191
            throw new RuntimeException(sprintf('transfer strategy with typeValue %d does not exist', $transferType->value));
192
        }
193
194
        return $this->transferStrategies[$transferType->value];
195
    }
196
197
    public function performSessionCheck(): bool
198
    {
199
        return true;
200
    }
201
}
202