Passed
Push — dev ( 1dcdd9...74922b )
by Janko
06:48
created

CrewCreator::createCrewAssignments()   B

Complexity

Conditions 9
Paths 8

Size

Total Lines 49
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 90

Importance

Changes 0
Metric Value
cc 9
eloc 30
nc 8
nop 3
dl 0
loc 49
ccs 0
cts 32
cp 0
crap 90
rs 8.0555
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Crew\Lib;
6
7
use InvalidArgumentException;
8
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...
9
use Stu\Component\Crew\CrewTypeEnum;
10
use Stu\Component\Crew\CrewOriginException;
11
use Stu\Exception\SanityCheckException;
12
use Stu\Module\Spacecraft\Lib\Crew\EntityWithCrewAssignmentsInterface;
13
use Stu\Orm\Entity\Colony;
14
use Stu\Orm\Entity\Crew;
15
use Stu\Orm\Entity\CrewAssignment;
16
use Stu\Orm\Entity\Spacecraft;
17
use Stu\Orm\Repository\CrewRaceRepositoryInterface;
18
use Stu\Orm\Repository\CrewRepositoryInterface;
19
use Stu\Orm\Repository\CrewAssignmentRepositoryInterface;
20
use Stu\Orm\Repository\ShipRumpCategoryRoleCrewRepositoryInterface;
21
use Stu\Orm\Repository\UserRepositoryInterface;
22
23
final class CrewCreator implements CrewCreatorInterface
24
{
25 1
    public function __construct(
26
        private CrewRaceRepositoryInterface $crewRaceRepository,
27
        private ShipRumpCategoryRoleCrewRepositoryInterface $shipRumpCategoryRoleCrewRepository,
28
        private CrewAssignmentRepositoryInterface $shipCrewRepository,
29
        private CrewRepositoryInterface $crewRepository,
30
        private UserRepositoryInterface $userRepository
31 1
    ) {}
32
33
    #[Override]
34
    public function create(int $userId, ?Colony $colony = null): CrewAssignment
35
    {
36
        $user = $this->userRepository->find($userId);
37
38
        if ($user === null) {
39
            throw new InvalidArgumentException('user not found1');
40
        }
41
42
        $arr = [];
43
        $raceList = $this->crewRaceRepository->getByFaction($user->getFactionId());
44
        foreach ($raceList as $obj) {
45
            $min = key($arr) + 1;
46
            $amount = range($min, $min + $obj->getChance());
47
            array_walk(
48
                $amount,
49
                function (&$value) use ($obj): void {
50
                    $value = $obj->getId();
51
                }
52
            );
53
            $arr = [...$arr, ...$amount];
54
        }
55
        $randomRaceId = $arr[array_rand($arr)];
56
        $race = $this->crewRaceRepository->find($randomRaceId);
57
        if ($race === null) {
58
            throw new SanityCheckException(sprintf('raceId %d does not exist', $randomRaceId));
59
        }
60
61
        $gender = random_int(1, 100) > $race->getMaleRatio() ? Crew::CREW_GENDER_FEMALE : Crew::CREW_GENDER_MALE;
62
63
        $crew = $this->crewRepository->prototype();
64
65
        $crew->setUser($user);
66
        $crew->setName('Crew');
67
        $crew->setRace($race);
68
        $crew->setGender($gender);
69
        $crew->setType(CrewTypeEnum::CREWMAN);
70
        $this->crewRepository->save($crew);
71
72
        $crewAssignment = $this->shipCrewRepository->prototype();
73
        $crewAssignment->setUser($user);
74
        $crewAssignment->setCrew($crew);
75
        if ($colony !== null) {
76
            $crewAssignment->setColony($colony);
77
            $colony->getCrewAssignments()->add($crewAssignment);
78
        }
79
        $this->shipCrewRepository->save($crewAssignment);
80
81
        return $crewAssignment;
82
    }
83
84
    #[Override]
85
    public function createCrewAssignments(
86
        Spacecraft $spacecraft,
87
        EntityWithCrewAssignmentsInterface $crewProvider,
88
        ?int $amount = null
89
    ): void {
90
        $crewToSetup = $amount ?? $spacecraft->getBuildPlan()?->getCrew() ?? 0;
91
        $shipRumpRole = $spacecraft->getRump()->getShipRumpRole();
92
        if ($shipRumpRole === null) {
93
            throw new SanityCheckException(sprintf('rumpId %d does not have rump role', $spacecraft->getRump()->getId()));
94
        }
95
96
        foreach (CrewTypeEnum::getOrder() as $crewType) {
97
            $createdcount = 1;
98
            $config = $this->shipRumpCategoryRoleCrewRepository->getByShipRumpCategoryAndRole(
99
                $spacecraft->getRump()->getShipRumpCategory()->getId(),
100
                $shipRumpRole->getId()
101
            );
102
            if ($config === null) {
103
                throw new InvalidArgumentException(sprintf(
104
                    'no rump category role crew for rumpCategoryId: %d, rumpRoleId: %d',
105
                    $spacecraft->getRump()->getShipRumpCategory()->getId()->value,
106
                    $shipRumpRole->getId()->value
107
                ));
108
            }
109
110
            while ($crewToSetup > 0 && ($crewType == CrewTypeEnum::CREWMAN || $createdcount <= $config->getCrewForPosition($crewType))) {
111
                $createdcount++;
112
                $crewToSetup--;
113
114
                $crewAssignment = $this->getCrewByType($crewType, $crewProvider);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $crewAssignment is correct as $this->getCrewByType($crewType, $crewProvider) targeting Stu\Module\Crew\Lib\CrewCreator::getCrewByType() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
115
                if ($crewAssignment === null) {
116
                    $crewAssignment = $this->getCrew($crewProvider);
117
                }
118
119
                if ($crewAssignment === null) {
120
                    throw new CrewOriginException('no assignable crew found');
121
                }
122
123
                $crewAssignment->setSpacecraft($spacecraft);
124
                $crewAssignment->setColony(null);
125
                $crewAssignment->setTradepost(null);
126
                //TODO set both ship and crew user
127
                $crewAssignment->setUser($spacecraft->getUser());
128
                $crewAssignment->setSlot($crewType);
129
130
                $spacecraft->getCrewAssignments()->add($crewAssignment);
131
132
                $this->shipCrewRepository->save($crewAssignment);
133
            }
134
        }
135
    }
136
137
    private function getCrewByType(
138
        CrewTypeEnum $crewType,
139
        EntityWithCrewAssignmentsInterface $crewProvider
140
    ): ?CrewAssignment {
141
142
        foreach ($crewProvider->getCrewAssignments() as $crewAssignment) {
143
            $crew = $crewAssignment->getCrew();
144
            if ($crew->getType() === $crewType) {
145
                $crewProvider->getCrewAssignments()->removeElement($crewAssignment);
146
147
                return $crewAssignment;
148
            }
149
        }
150
151
        return null;
152
    }
153
154
    private function getCrew(EntityWithCrewAssignmentsInterface $crewProvider): ?CrewAssignment
155
    {
156
        $crewAssignments = $crewProvider->getCrewAssignments();
157
158
        if ($crewAssignments->isEmpty()) {
159
            return null;
160
        }
161
162
        /** @var CrewAssignment $random */
163
        $random = $crewAssignments->get(array_rand($crewAssignments->toArray()));
0 ignored issues
show
Bug introduced by
It seems like array_rand($crewAssignments->toArray()) can also be of type array; however, parameter $key of Doctrine\Common\Collecti...adableCollection::get() does only seem to accept integer|string, maybe add an additional type check? ( Ignorable by Annotation )

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

163
        $random = $crewAssignments->get(/** @scrutinizer ignore-type */ array_rand($crewAssignments->toArray()));
Loading history...
164
165
        $crewAssignments->removeElement($random);
166
167
        return $random;
168
    }
169
}
170