Test Failed
Push — dev ( 202013...51a7a9 )
by Nico
11:19
created

TechlistRetriever::getResearchList()   C

Complexity

Conditions 17
Paths 100

Size

Total Lines 76
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 306

Importance

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