TechlistRetriever::getResearchList()   C
last analyzed

Complexity

Conditions 17
Paths 100

Size

Total Lines 87
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 29.1586

Importance

Changes 0
Metric Value
cc 17
eloc 43
nc 100
nop 1
dl 0
loc 87
ccs 30
cts 46
cp 0.6522
crap 29.1586
rs 5.2166
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\Research;
6
7
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...
8
use Stu\Component\Research\ResearchModeEnum;
9
use Stu\Orm\Entity\Researched;
10
use Stu\Orm\Entity\Research;
11
use Stu\Orm\Entity\ResearchDependency;
12
use Stu\Orm\Entity\User;
13
use Stu\Orm\Repository\FactionRepositoryInterface;
14
use Stu\Orm\Repository\ResearchDependencyRepositoryInterface;
15
use Stu\Orm\Repository\ResearchedRepositoryInterface;
16
use Stu\Orm\Repository\ResearchRepositoryInterface;
17
18
final class TechlistRetriever implements TechlistRetrieverInterface
19
{
20 1
    public function __construct(private ResearchRepositoryInterface $researchRepository, private ResearchDependencyRepositoryInterface $researchDependencyRepository, private ResearchedRepositoryInterface $researchedRepository, private FactionRepositoryInterface $factionRepository) {}
21
22 4
    #[Override]
23
    public function getResearchList(User $user): array
24
    {
25 4
        $researchedList = $this->getResearchedList($user);
26
27 4
        $researchedIdsWithUnfinished = array_map(
28 4
            fn(Researched $researched): int => $researched->getResearch()->getId(),
29 4
            $researchedList
30 4
        );
31
32 4
        $researchedIdsOnlyFinished = array_map(
33 4
            fn(Researched $researched): int => $researched->getResearch()->getId(),
34 4
            array_filter(
35 4
                $researchedList,
36 4
                fn(Researched $researched): bool => $researched->getFinished() > 0
37 4
            )
38 4
        );
39
40 4
        $result = $this->researchRepository->getAvailableResearch($user->getId());
41 4
        $list_result = [];
42
43
        //load dependencies
44 4
        $allDependencies = $this->loadDependencies();
45
46
        //load excludes
47 4
        $excludes = $this->loadExcludes();
48
49
        // calculate possible research items
50 4
        foreach ($result as $research) {
51
            // check for existent user award
52 4
            if ($research->getNeededAwardId() !== null && !$user->hasAward($research->getNeededAwardId())) {
53
                continue;
54
            }
55
56 4
            $researchId = $research->getId();
57
58
            // excludelogic
59 4
            if (isset($excludes[$researchId])) {
60
                foreach ($excludes[$researchId] as $exclude) {
61
                    if (in_array($exclude->getResearchId(), $researchedIdsWithUnfinished)) {
62
                        continue 2;
63
                    }
64
                }
65
            }
66
67
            // dependency logic
68 4
            if (isset($allDependencies[$researchId])) {
69
70
                $dependencies = $allDependencies[$researchId];
71
72
                // check for AND condition
73
                foreach ($dependencies['AND'] as $and_condition) {
74
                    if (!in_array($and_condition, $researchedIdsOnlyFinished)) {
75
                        continue 2;
76
                    }
77
                }
78
79
                // check for OR condition
80
                if (!empty($dependencies['OR'])) {
81
                    $or_condition_met = false;
82
                    foreach ($dependencies['OR'] as $or_condition) {
83
                        if (in_array($or_condition, $researchedIdsOnlyFinished)) {
84
                            $or_condition_met = true;
85
                            break;
86
                        }
87
                    }
88
                    if (!$or_condition_met) {
89
                        continue;
90
                    }
91
                }
92
            }
93
94 4
            $list_result[$researchId] = $research;
95
        }
96
97
98 4
        foreach ($this->factionRepository->findAll() as $faction) {
99 4
            $startResearch = $faction->getStartResearch();
100 4
            if ($startResearch !== null) {
101 4
                $startResearchId = $startResearch->getId();
102 4
                if (isset($list_result[$startResearchId])) {
103 4
                    unset($list_result[$startResearchId]);
104
                }
105
            }
106
        }
107
108 4
        return $list_result;
109
    }
110
111
    #[Override]
112
    public function canResearch(User $user, int $researchId): ?Research
113
    {
114
        return $this->getResearchList($user)[$researchId] ?? null;
115
    }
116
117
    /** @return array<int, array<string, array<int>>> */
118 4
    private function loadDependencies(): array
119
    {
120 4
        $allDependencies = [];
121
122 4
        $allDependencies_result = $this->researchDependencyRepository->getByMode(
123 4
            [ResearchModeEnum::REQUIRE->value, ResearchModeEnum::REQUIRE_SOME->value]
124 4
        );
125
126 4
        foreach ($allDependencies_result as $dependency) {
127
            $research_id = $dependency->getResearchId();
128
            $mode = $dependency->getMode();
129
130
            if (!isset($allDependencies[$research_id])) {
131
                $allDependencies[$research_id] = [
132
                    'AND' => [],
133
                    'OR' => []
134
                ];
135
            }
136
137
            if ($mode === ResearchModeEnum::REQUIRE) {
138
                $allDependencies[$research_id]['AND'][] = $dependency->getDependsOn();
139
            } elseif ($mode === ResearchModeEnum::REQUIRE_SOME) {
140
                $allDependencies[$research_id]['OR'][] = $dependency->getDependsOn();
141
            }
142
        }
143
144 4
        return $allDependencies;
145
    }
146
147
    /** @return array<int, array<ResearchDependency>> */
148 4
    private function loadExcludes(): array
149
    {
150 4
        $excludes = [];
151 4
        $exclude_result = $this->researchDependencyRepository->getByMode([ResearchModeEnum::EXCLUDE->value]);
152
153 4
        foreach ($exclude_result as $dependency) {
154
            $research_id = $dependency->getDependsOn();
155
            if (array_key_exists($research_id, $excludes) === false) {
156
                $excludes[$research_id] = [];
157
            }
158
            $excludes[$research_id][] = $dependency;
159
        }
160
161 4
        return $excludes;
162
    }
163
164 4
    #[Override]
165
    public function getResearchedList(User $user): array
166
    {
167 4
        return $this->researchedRepository->getListByUser($user->getId());
168
    }
169
}
170