Passed
Push — master ( 69410e...6e6431 )
by Nico
42:43 queued 11:08
created

TechlistRetriever::canResearch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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