TransferToClosestLocation::transfer()   C
last analyzed

Complexity

Conditions 13
Paths 36

Size

Total Lines 68
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 43
CRAP Score 13

Importance

Changes 0
Metric Value
cc 13
eloc 40
nc 36
nop 4
dl 0
loc 68
ccs 43
cts 43
cp 1
crap 13
rs 6.6166
c 0
b 0
f 0

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\Spacecraft\Action\SalvageEmergencyPods;
6
7
use Stu\Lib\Map\DistanceCalculationInterface;
8
use Stu\Orm\Entity\Spacecraft;
9
use Stu\Orm\Entity\TradePost;
10
use Stu\Orm\Repository\CrewAssignmentRepositoryInterface;
11
12
final class TransferToClosestLocation
13
{
14 9
    public function __construct(
15
        private ClosestLocations $closestLocations,
16
        private DistanceCalculationInterface $distanceCalculation,
17
        private CrewAssignmentRepositoryInterface $shipCrewRepository
18 9
    ) {}
19
20 8
    public function transfer(
21
        Spacecraft $ship,
22
        Spacecraft $target,
23
        int $crewCount,
24
        TradePost $closestTradepost
25
    ): string {
26 8
        $closestColony = null;
27 8
        $colonyDistance = null;
28
29 8
        $closestColonyArray = $this->closestLocations->searchClosestUsableColony($ship, $crewCount);
30 8
        if ($closestColonyArray !== null) {
31 5
            [$colonyDistance, $closestColony] = $closestColonyArray;
32
        }
33
34 8
        $stationDistance = null;
35 8
        $closestStation = null;
36 8
        $closestStationArray = $this->closestLocations->searchClosestUsableStation($ship, $crewCount);
37 8
        if ($closestStationArray !== null) {
38 5
            [$stationDistance, $closestStation] = $closestStationArray;
39
        }
40
41
42 8
        $tradepostDistance = $this->distanceCalculation->shipToShipDistance($ship, $closestTradepost->getStation());
43 8
        $minimumDistance = $this->getMinimumDistance($colonyDistance, $stationDistance, $tradepostDistance);
44
45
        //transfer to closest colony
46 8
        if ($colonyDistance === $minimumDistance && $closestColony !== null) {
47 2
            foreach ($target->getCrewAssignments() as $crewAssignment) {
48 2
                if ($crewAssignment->getCrew()->getUser() === $ship->getUser()) {
49 2
                    $crewAssignment->setColony($closestColony);
50 2
                    $crewAssignment->setSpacecraft(null);
51 2
                    $this->shipCrewRepository->save($crewAssignment);
52
                }
53
            }
54 2
            return sprintf(
55 2
                _('Deine Crew wurde geborgen und an die Kolonie "%s" (%s) überstellt'),
56 2
                $closestColony->getName(),
57 2
                $closestColony->getSectorString()
58 2
            );
59
        }
60
61
        //transfer to closest station
62 6
        if ($stationDistance === $minimumDistance && $closestStation !== null) {
63 2
            foreach ($target->getCrewAssignments() as $crewAssignment) {
64 2
                if ($crewAssignment->getCrew()->getUser() === $ship->getUser()) {
65 2
                    $crewAssignment->setSpacecraft($closestStation);
66 2
                    $this->shipCrewRepository->save($crewAssignment);
67
                }
68
            }
69 2
            return sprintf(
70 2
                _('Deine Crew wurde geborgen und an die Station "%s" (%s) überstellt'),
71 2
                $closestStation->getName(),
72 2
                $closestStation->getSectorString()
73 2
            );
74
        }
75
76
        //transfer to closest tradepost
77 4
        foreach ($target->getCrewAssignments() as $crewAssignment) {
78 4
            if ($crewAssignment->getCrew()->getUser() === $ship->getUser()) {
79 4
                $crewAssignment->setSpacecraft(null);
80 4
                $crewAssignment->setTradepost($closestTradepost);
81 4
                $this->shipCrewRepository->save($crewAssignment);
82
            }
83
        }
84 4
        return sprintf(
85 4
            _('Deine Crew wurde geborgen und an den Handelsposten "%s" (%s) überstellt'),
86 4
            $closestTradepost->getName(),
87 4
            $closestTradepost->getStation()->getSectorString()
88 4
        );
89
    }
90
91 8
    private function getMinimumDistance(?int $colonyDistance, ?int $stationDistance, int $tradePostDistance): int
92
    {
93 8
        return min(
94 8
            $colonyDistance ?? PHP_INT_MAX,
95 8
            $stationDistance ?? PHP_INT_MAX,
96 8
            $tradePostDistance
97 8
        );
98
    }
99
}
100