RuleConfigBuilder   A
last analyzed

Complexity

Total Complexity 40

Size/Duplication

Total Lines 254
Duplicated Lines 0 %

Test Coverage

Coverage 86.93%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 40
eloc 135
c 1
b 0
f 0
dl 0
loc 254
ccs 133
cts 153
cp 0.8693
rs 9.2

21 Methods

Rating   Name   Duplication   Size   Complexity  
A getInjuries() 0 3 1
A setInducementTable() 0 4 1
A setSkills() 0 4 1
A setInjuries() 0 4 1
A setRosters() 0 4 1
A setInducementTypes() 0 4 1
A setSppLevels() 0 4 1
A prepareSkillsTable() 0 15 3
A prepareRosterTable() 0 14 2
A getSkills() 0 3 1
A getInducementType() 0 3 1
A prepareSppTable() 0 16 5
A prepareInducementTable() 0 25 6
A getRosters() 0 3 1
A prepareInducementTypes() 0 17 1
A prepareInjuriesTable() 0 17 4
A build() 0 10 1
A createStarPlayerInducement() 0 27 5
A getInducementTable() 0 3 1
A getInducementTypes() 0 3 1
A getSppLevels() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like RuleConfigBuilder often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use RuleConfigBuilder, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Obblm\Core\Helper\Rule;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Obblm\Core\Contracts\InducementInterface;
7
use Obblm\Core\Contracts\RosterInterface;
8
use Obblm\Core\Contracts\Rule\RuleBuilderInterface;
9
use Obblm\Core\Helper\CoreTranslation;
10
use Obblm\Core\Helper\Rule\Config\ConfigResolver;
11
use Obblm\Core\Helper\Rule\Config\RuleConfigResolver;
12
use Obblm\Core\Helper\Rule\Inducement\Inducement;
13
use Obblm\Core\Helper\Rule\Inducement\InducementType;
14
use Obblm\Core\Helper\Rule\Inducement\MultipleStarPlayer;
15
use Obblm\Core\Helper\Rule\Inducement\StarPlayer;
16
use Obblm\Core\Helper\Rule\Roster\Roster;
17
use Obblm\Core\Helper\Rule\Skill\Skill;
18
19
class RuleConfigBuilder extends RuleConfigResolver implements RuleBuilderInterface
20
{
21
    /** @var ArrayCollection */
22
    private $injuries;
23
    /** @var ArrayCollection|Skill[] */
24
    private $skills;
25
    /** @var ArrayCollection|InducementType[] */
26
    private $inducementTypes;
27
    /** @var ArrayCollection */
28
    private $sppLevels;
29
    /** @var ArrayCollection|InducementInterface[] */
30
    private $inducements;
31
    /** @var ArrayCollection|RosterInterface[] */
32
    private $rosters;
33
34 1
    protected function build(string $ruleKey, array $rule)
35
    {
36 1
        $treeResolver = new ConfigResolver($this);
37 1
        $rule = $treeResolver->resolve($rule);
38 1
        $this->prepareInjuriesTable($ruleKey, $rule);
39 1
        $this->prepareSppTable($ruleKey, $rule);
40 1
        $this->prepareSkillsTable($ruleKey, $rule);
41 1
        $this->prepareInducementTypes($ruleKey);
42 1
        $this->prepareInducementTable($ruleKey, $rule);
43 1
        $this->prepareRosterTable($ruleKey, $rule);
44 1
    }
45
46
    public function getInjuries():ArrayCollection
47
    {
48
        return $this->injuries;
49
    }
50
51
    public function setInjuries(ArrayCollection $injuries):self
52
    {
53
        $this->injuries = $injuries;
54
        return $this;
55
    }
56
57 2
    public function getInducementTypes():ArrayCollection
58
    {
59 2
        return $this->inducementTypes;
60
    }
61
62
    public function setInducementTypes(ArrayCollection $inducementTypes):self
63
    {
64
        $this->inducementTypes = $inducementTypes;
65
        return $this;
66
    }
67
68 2
    public function getInducementType(string $type):InducementType
69
    {
70 2
        return $this->getInducementTypes()->get($type);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getInducementTypes()->get($type) could return the type null which is incompatible with the type-hinted return Obblm\Core\Helper\Rule\Inducement\InducementType. Consider adding an additional type-check to rule them out.
Loading history...
71
    }
72
73 1
    public function getSppLevels():ArrayCollection
74
    {
75 1
        return $this->sppLevels;
76
    }
77
78
    public function setSppLevels(ArrayCollection $sppLevels):self
79
    {
80
        $this->sppLevels = $sppLevels;
81
        return $this;
82
    }
83
84 2
    public function getInducementTable():ArrayCollection
85
    {
86 2
        return $this->inducements;
87
    }
88
89
    public function setInducementTable(ArrayCollection $inducements):self
90
    {
91
        $this->inducements = $inducements;
92
        return $this;
93
    }
94
95 4
    public function getRosters():ArrayCollection
96
    {
97 4
        return $this->rosters;
98
    }
99
100
    public function setRosters(ArrayCollection $rosters):self
101
    {
102
        $this->rosters = $rosters;
103
        return $this;
104
    }
105
106 2
    public function getSkills():ArrayCollection
107
    {
108 2
        return $this->skills;
109
    }
110
111
    public function setSkills(ArrayCollection $skills):self
112
    {
113
        $this->skills = $skills;
114
        return $this;
115
    }
116
117 1
    private function prepareInjuriesTable(string $ruleKey, array $rule)
118
    {
119 1
        $this->injuries = new ArrayCollection();
120 1
        foreach ($rule['injuries'] as $key => $injury) {
121 1
            $label = CoreTranslation::getInjuryKey($ruleKey, $key);
122 1
            $effectLabel = CoreTranslation::getInjuryEffect($ruleKey, $key);
123 1
            if (isset($injury['to'])) {
124 1
                for ($i = $injury['from']; $i <= $injury['to']; $i++) {
125 1
                    $this->injuries->set(
126 1
                        $i,
127 1
                        (object) ['value' => $i, 'label' => $label, 'effect_label' => $effectLabel, 'effects' => $injury['effects']]
128
                    );
129
                }
130
            } else {
131 1
                $this->injuries->set(
132 1
                    $injury['from'],
133 1
                    (object) ['value' => $injury['from'], 'label' => $label, 'effect_label' => $effectLabel, 'effects' => $injury['effects']]
134
                );
135
            }
136
        }
137 1
    }
138
139 1
    private function prepareInducementTypes(string $ruleKey)
140
    {
141 1
        $this->inducementTypes = new ArrayCollection();
142 1
        $this->inducementTypes->set('star_players', new InducementType([
143 1
            'key' => 'star_players',
144 1
            'name' => CoreTranslation::getStarPlayerTitle($ruleKey),
145 1
            'translation_domain' => $ruleKey,
146
        ]));
147 1
        $this->inducementTypes->set('inducements', new InducementType([
148 1
            'key' => 'inducements',
149 1
            'name' => CoreTranslation::getInducementTitle($ruleKey),
150 1
            'translation_domain' => $ruleKey,
151
        ]));
152 1
        $this->inducementTypes->set('mercenary', new InducementType([
153 1
            'key' => 'mercenary',
154 1
            'name' => CoreTranslation::getMercenaryTitle($ruleKey),
155 1
            'translation_domain' => $ruleKey,
156
        ]));
157 1
    }
158
159 1
    private function prepareSppTable(string $ruleKey, array $rule)
160
    {
161 1
        $spps = new ArrayCollection($rule['spp_levels']);
162 1
        foreach ($spps as $from => $level) {
163 1
            $to = $spps->next();
164 1
            if ($to) {
165 1
                for ($i = $from; $i < $spps->indexOf($to); $i++) {
166 1
                    if (!isset($spps[$i])) {
167 1
                        $spps[$i] = $level;
168
                    }
169
                }
170
            }
171
        }
172 1
        $spps = $spps->toArray();
173 1
        ksort($spps);
174 1
        $this->sppLevels = new ArrayCollection($spps);
175 1
    }
176
177 1
    private function prepareSkillsTable(string $ruleKey, array $rule)
178
    {
179 1
        $this->skills = new ArrayCollection();
180 1
        foreach ($rule['skills'] as $type => $skills) {
181 1
            foreach ($skills as $skill) {
182 1
                $key = join(CoreTranslation::TRANSLATION_GLUE, [$type, $skill]);
183 1
                $this->skills->set(
184 1
                    $key,
185 1
                    new Skill([
186 1
                        'key'         => $skill,
187 1
                        'type'        => $type,
188 1
                        'name'        => CoreTranslation::getSkillNameKey($ruleKey, $skill),
189 1
                        'description' => CoreTranslation::getSkillDescription($ruleKey, $skill),
190 1
                        'type_name'   => CoreTranslation::getSkillType($ruleKey, $type),
191 1
                        'translation_domain'      => $ruleKey,
192
                    ])
193
                );
194
            }
195
        }
196 1
    }
197
198 1
    private function prepareInducementTable(string $ruleKey, array $rule)
199
    {
200 1
        $this->inducements = new ArrayCollection();
201
202 1
        foreach ($rule['inducements'] as $key => $value) {
203 1
            if ($key !== 'star_players') {
204 1
                $inducement = new Inducement([
205 1
                    'type' => $this->inducementTypes['inducements'],
206 1
                    'key' => join(CoreTranslation::TRANSLATION_GLUE, [$ruleKey, 'inducements', $key]),
207 1
                    'translation_domain' => $ruleKey,
208 1
                    'name' => CoreTranslation::getInducementName($ruleKey, $key),
209 1
                    'max' => $value['max'] ?? 0,
210 1
                    'rosters' => $value['rosters'] ?? null,
211 1
                    'value' => $value['cost'],
212 1
                    'discount_value' => $value['discount_cost'] ?? null,
213
                ]);
214 1
                if (!$this->inducements->contains($inducement)) {
215 1
                    $this->inducements->add($inducement);
216
                }
217
            }
218
        }
219 1
        foreach ($rule['star_players'] as $key => $starPlayer) {
220 1
            $inducement = $this->createStarPlayerInducement($ruleKey, $key, $starPlayer);
221 1
            if (!$this->inducements->contains($inducement)) {
222 1
                $this->inducements->add($inducement);
223
            }
224
        }
225 1
    }
226
227 1
    private function prepareRosterTable(string $ruleKey, array $rule)
228
    {
229 1
        $this->rosters = new ArrayCollection();
230 1
        foreach ($rule['rosters'] as $key => $roster) {
231 1
            $this->rosters->set(
232 1
                $key,
233 1
                new Roster([
234 1
                    'key' => $key,
235 1
                    'name' => CoreTranslation::getRosterKey($ruleKey, $key),
236 1
                    'translation_domain' => $ruleKey,
237 1
                    'player_types' => $roster['players'],
238 1
                    'reroll_cost' => $roster['reroll_cost'] ?? 0,
239 1
                    'can_have_apothecary' => $roster['options']['can_have_apothecary'] ?? true,
240 1
                    'inducement_options' => $roster['options']['inducements'] ?? [],
241
                ])
242
            );
243
        }
244 1
    }
245
246 1
    private function createStarPlayerInducement(string $ruleKey, string $key, array $starPlayer):InducementInterface
247
    {
248
        $options = [
249 1
            'type' => $this->inducementTypes['star_players'],
250 1
            'key' => join(CoreTranslation::TRANSLATION_GLUE, [$ruleKey, 'star_players', $key]),
251 1
            'value' => $starPlayer['cost'],
252 1
            'discount_value' => $starPlayer['discount_cost'] ?? null,
253 1
            'translation_domain' => $ruleKey,
254 1
            'name' => CoreTranslation::getStarPlayerName($ruleKey, $key),
255 1
            'max' => $starPlayer['max'] ?? 1,
256 1
            'characteristics' => $starPlayer['characteristics'] ?? null,
257 1
            'skills' => $starPlayer['skills'] ?? null,
258 1
            'rosters' => $starPlayer['rosters'] ?? null,
259
        ];
260 1
        if (isset($starPlayer['multi_parts']) && $starPlayer['multi_parts']) {
261 1
            $options['parts'] = [];
262 1
            $first = true;
263 1
            foreach ($starPlayer['multi_parts'] as $key => $part) {
264 1
                $part['cost'] = $first ? $starPlayer['cost'] : 0;
265 1
                $options['parts'][] = $this->createStarPlayerInducement($ruleKey, $key, $part);
266 1
                $first = false;
267
            }
268 1
            $inducement = new MultipleStarPlayer($options);
269
        } else {
270 1
            $inducement = new StarPlayer($options);
271
        }
272 1
        return $inducement;
273
    }
274
}
275