Test Failed
Push — master ( 16cd80...2162ae )
by Julien
30:16
created

Fight   C

Complexity

Total Complexity 58

Size/Duplication

Total Lines 280
Duplicated Lines 6.43 %

Coupling/Cohesion

Components 3
Dependencies 7

Importance

Changes 9
Bugs 1 Features 1
Metric Value
wmc 58
c 9
b 1
f 1
lcom 3
cbo 7
dl 18
loc 280
rs 6.3005

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A group() 0 4 1
A competitor1() 0 4 1
A competitor2() 0 4 1
A team1() 0 4 1
A team2() 0 4 1
C savePreliminaryFightGroup() 0 40 8
C getActorsToFights() 12 25 7
B saveGroupFights() 0 33 5
B getFighterAttr() 0 17 7
B updateParentFight() 6 13 9
B getParentFighterToUpdate() 0 16 5
B getValueToUpdate() 0 13 5
B hasDeterminedParent() 0 10 6

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Fight 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 Fight, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Xoco70\KendoTournaments\Models;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Support\Collection;
7
8
class Fight extends Model
9
{
10
    /**
11
     * Fight constructor.
12
     * @param int $userId1
13
     * @param int $userId2
14
     */
15
    public function __construct($userId1 = null, $userId2 = null)
16
    {
17
        $this->c1 = $userId1;
18
        $this->c2 = $userId2;
19
    }
20
21
    protected $table = 'fight';
22
    public $timestamps = true;
23
24
    protected $fillable = [
25
        'group_id',
26
        'c1',
27
        'c2',
28
    ];
29
30
    /**
31
     * Get First Fighter.
32
     *
33
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
34
     */
35
    public function group()
36
    {
37
        return $this->belongsTo(FightersGroup::class, 'fighters_group_id');
38
    }
39
40
    /**
41
     * @param Championship $championship
42
     *
43
     * @return Collection
44
     */
45
    private static function getActorsToFights(Championship $championship, FightersGroup $group = null)
46
    {
47
        if ($group != null) {
48
            if ($championship->category->isTeam) {
49
                $fighters = $group->teams()->get();
50 View Code Duplication
                if (sizeof($fighters) == 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
51
                    $fighters->push(new Team());
52
                    $fighters->push(new Team());
53
                } else if (count($fighters) % 2 != 0) {
54
                    $fighters->push(new Team(['name' => 'BYE']));
55
                }
56
                return $fighters;
57
            } else {
58
                $fighters = $group->competitors()->get();
59 View Code Duplication
                if (sizeof($fighters) == 0) { // If
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
60
                    $fighters->push(new Competitor());
61
                    $fighters->push(new Competitor());
62
                } else if (count($fighters) % 2 != 0) { // If fighter is not pair, add a BYE
63
                    $fighters->push(new Competitor());
64
                }
65
            }
66
            return $fighters;
67
        }
68
        return null;
69
    }
70
71
    /**
72
     * Get First Fighter.
73
     *
74
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
75
     */
76
    public function competitor1()
77
    {
78
        return $this->belongsTo(Competitor::class, 'c1', 'id');
79
    }
80
81
    /**
82
     * Get Second Fighter.
83
     *
84
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
85
     */
86
    public function competitor2()
87
    {
88
        return $this->belongsTo(Competitor::class, 'c2', 'id');
89
    }
90
91
    /**
92
     * Get First Fighter.
93
     *
94
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
95
     */
96
    public function team1()
97
    {
98
        return $this->belongsTo(Team::class, 'c1', 'id');
99
    }
100
101
    /**
102
     * Get Second Fighter.
103
     *
104
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
105
     */
106
    public function team2()
107
    {
108
        return $this->belongsTo(Team::class, 'c2', 'id');
109
    }
110
111
    /**
112
     * Save a Fight.
113
     *
114
     * @param Collection $groups
115
     * @param int $numGroup
116
     */
117
    public static function savePreliminaryFightGroup($groups, $numGroup = 1)
118
    {
119
        $competitor1 = $competitor2 = null;
120
        $order = 1;
121
122
        foreach ($groups as $group) {
123
124
            if ($group->championship->category->isTeam()) {
125
                $fighters = $group->teams;
126
            } else {
127
                $fighters = $group->competitors;
128
            }
129
130
            $fighter1 = $fighters->get(0);
131
            $fighter2 = $fighters->get(1);
132
            $fighter3 = $fighters->get(2);
133
134
            switch ($numGroup) {
135
                case 1:
136
                    $competitor1 = $fighter1;
137
                    $competitor2 = $fighter2;
138
                    break;
139
                case 2:
140
                    $competitor1 = $fighter2;
141
                    $competitor2 = $fighter3;
142
                    break;
143
                case 3:
144
                    $competitor1 = $fighter3;
145
                    $competitor2 = $fighter1;
146
                    break;
147
            }
148
            $fight = new self();
149
            $fight->fighters_group_id = $group->id;
150
            $fight->c1 = $competitor1 != null ? $competitor1->id : null;
151
            $fight->c2 = $competitor2 != null ? $competitor2->id : null;
152
            $fight->short_id = $order++;
153
            $fight->area = $group->area;
154
            $fight->save();
155
        }
156
    }
157
158
159
    /**
160
     * @param Championship $championship
161
     */
162
    public static function saveGroupFights(Championship $championship)
163
    {
164
        $order = 1;
165
        $round = [];
166
        foreach ($championship->fightersGroups()->get() as $group) {
167
            $fighters = self::getActorsToFights($championship, $group);
168
            $away = $fighters->splice(count($fighters) / 2); // 2
169
            $home = $fighters; // 1
170
171
            $countHome = count($home);
172
            $countAway = count($away);
173
            for ($i = 0; $i < $countHome + $countAway - 1; $i++) {
174
                for ($j = 0; $j < $countHome; $j++) {
175
176
                    $round[$i][$j]['Home'] = $home[$j];
177
                    $round[$i][$j]['Away'] = $away[$j];
178
                    $fight = new self();
179
                    $fight->fighters_group_id = $group->id;
180
                    $fight->c1 = $round[$i][$j]['Home']->id;
181
                    $fight->c2 = $round[$i][$j]['Away']->id;
182
                    $fight->short_id = $order++;
183
                    $fight->area = $group->area;
184
                    $fight->save();
185
186
                }
187
                if ($countHome + $countAway - 1 > 2) {
188
                    $away->prepend($home->splice(1, 1)->shift());
189
                    $home->push($away->pop());
190
                    $order++;
191
                }
192
            }
193
        }
194
    }
195
196
    public function getFighterAttr($numFighter, $attr)
197
    {
198
        $isTeam = $this->group->championship->category->isTeam;
199
        if ($isTeam) {
200
            $teamToUpdate = 'team' . $numFighter;
201
            return $this->$teamToUpdate == null ? '' : $this->$teamToUpdate->$attr;
202
        }
203
        $competitorToUpdate = 'competitor' . $numFighter;
204
        if ($attr == 'name') {
205
            return $this->$competitorToUpdate == null
206
                ? 'BYE'
207
                : $this->$competitorToUpdate->user->firstname . " " . $this->$competitorToUpdate->user->lastname;
208
        } elseif ($attr == 'short_id') {
209
            return $this->$competitorToUpdate == null ? '' : $this->$competitorToUpdate->short_id;
210
        }
211
        return null;
212
    }
213
214
    /**
215
     * Update parent Fight
216
     */
217
    public function updateParentFight($fighterToUpdate, $fight)
218
    {
219
220 View Code Duplication
        if ($fight != null && ($fight->c1 != null || $fight->c2 == null)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
221
            $this->$fighterToUpdate = $fight->c1;
222
        }
223 View Code Duplication
        if ($fight != null && $fight->c1 == null || $fight->c2 != null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
224
            $this->$fighterToUpdate = $fight->c2;
225
        }
226
        if ($fight->c1 == null || $fight->c2 == null) {
227
            $this->$fighterToUpdate = null;
228
        }
229
    }
230
231
    /**
232
     * Returns the parent field that need to be updated
233
     * @return null|string
234
     */
235
    public function getParentFighterToUpdate()
236
    {
237
        $childrenGroup = $this->group->parent->children;
238
        foreach ($childrenGroup as $key => $children) {
239
            $childFight = $children->fights->get(0);
240
            if ($childFight->id == $this->id) {
241
                if ($key % 2 == 0) {
242
                    return "c1";
243
                }
244
                if ($key % 2 == 1) {
245
                    return "c2";
246
                }
247
            }
248
        }
249
        return null;
250
    }
251
252
    /**
253
     * In the original fight ( child ) return the field that contains data to copy to parent
254
     * @return null|string
255
     */
256
    public function getValueToUpdate()
257
    {
258
        if ($this->c1 != null && $this->c2 != null) {
259
            return null;
260
        }
261
        if ($this->c1 != null) {
262
            return "c1";
263
        }
264
        if ($this->c2 != null) {
265
            return "c2";
266
        }
267
        return null;
268
    }
269
270
    /**
271
     * Check if we are able to fill the parent fight or not
272
     * If one of the children has c1 x c2, then we must wait to fill parent
273
     *
274
     * @return bool
275
     */
276
    function hasDeterminedParent()
277
    {
278
279
        if ($this->c1 != null && $this->c2 != null) return true;
280
        foreach ($this->group->children as $child) {
281
            $fight = $child->fights->get(0);
282
            if ($fight->c1 != null && $fight->c2 != null) return false;
283
        }
284
        return true;
285
    }
286
287
}