Completed
Push — master ( f65102...332511 )
by Julien
02:46
created

Fight   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 232
Duplicated Lines 16.38 %

Coupling/Cohesion

Components 4
Dependencies 3

Importance

Changes 11
Bugs 2 Features 1
Metric Value
dl 38
loc 232
c 11
b 2
f 1
wmc 45
lcom 4
cbo 3
rs 8.3673

17 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
B getFighterAttr() 0 17 7
A getFightersWithByes() 0 14 4
B getParentFighterToUpdate() 16 16 5
B getValueToUpdate() 13 13 5
A hasDeterminedParent() 9 9 4
A shouldBeInFightList() 0 16 4
A has2Fighters() 0 4 2
A belongsToFirstRound() 0 6 2
A dontHave2Fighters() 0 4 2
A generateFightsId() 0 7 2
A updateShortId() 0 9 2

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
    /**
32
     * Get First Fighter.
33
     *
34
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
35
     */
36
    public function group()
37
    {
38
        return $this->belongsTo(FightersGroup::class, 'fighters_group_id');
39
    }
40
41
    /**
42
     * @param FightersGroup|null $group
43
     * @return Collection
44
     * @internal param Championship $championship
45
     *
46
     */
47
    protected static function getFightersWithByes(FightersGroup $group)
48
    {
49
        if ($group == null) return null;
50
        $fighters = $group->getFighters();
51
        $fighterType = $group->getFighterType();
52
        if (sizeof($fighters) == 0) {
53
            $fighters->push(new $fighterType);
54
            $fighters->push(new $fighterType);
55
        } else if (count($fighters) % 2 != 0) {
56
            $fighters->push(new $fighterType);
57
        }
58
59
        return $fighters;
60
    }
61
62
    /**
63
     * Get First Fighter.
64
     *
65
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
66
     */
67
    public function competitor1()
68
    {
69
        return $this->belongsTo(Competitor::class, 'c1', 'id');
70
    }
71
72
    /**
73
     * Get Second Fighter.
74
     *
75
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
76
     */
77
    public function competitor2()
78
    {
79
        return $this->belongsTo(Competitor::class, 'c2', 'id');
80
    }
81
82
    /**
83
     * Get First Fighter.
84
     *
85
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
86
     */
87
    public function team1()
88
    {
89
        return $this->belongsTo(Team::class, 'c1', 'id');
90
    }
91
92
    /**
93
     * Get Second Fighter.
94
     *
95
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
96
     */
97
    public function team2()
98
    {
99
        return $this->belongsTo(Team::class, 'c2', 'id');
100
    }
101
102
103
    public function getFighterAttr($numFighter, $attr)
104
    {
105
        $isTeam = $this->group->championship->category->isTeam;
106
        if ($isTeam) {
107
            $teamToUpdate = 'team' . $numFighter;
108
            return $this->$teamToUpdate == null ? '' : $this->$teamToUpdate->$attr;
109
        }
110
        $competitorToUpdate = 'competitor' . $numFighter;
111
        if ($attr == 'name') {
112
            return $this->$competitorToUpdate == null
113
                ? 'BYE'
114
                : $this->$competitorToUpdate->user->firstname . " " . $this->$competitorToUpdate->user->lastname;
115
        } elseif ($attr == 'short_id') {
116
            return $this->$competitorToUpdate == null ? '' : $this->$competitorToUpdate->short_id;
117
        }
118
        return null;
119
    }
120
121
122
123
    /**
124
     * Returns the parent field that need to be updated
125
     * @return null|string
126
     */
127 View Code Duplication
    public function getParentFighterToUpdate()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
128
    {
129
        $childrenGroup = $this->group->parent->children;
130
        foreach ($childrenGroup as $key => $children) {
131
            $childFight = $children->fights->get(0);
132
            if ($childFight->id == $this->id) {
133
                if ($key % 2 == 0) {
134
                    return "c1";
135
                }
136
                if ($key % 2 == 1) {
137
                    return "c2";
138
                }
139
            }
140
        }
141
        return null;
142
    }
143
144
    /**
145
     * In the original fight ( child ) return the field that contains data to copy to parent
146
     * @return null|string
147
     */
148 View Code Duplication
    public function getValueToUpdate()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
149
    {
150
        if ($this->c1 != null && $this->c2 != null) {
151
            return null;
152
        }
153
        if ($this->c1 != null) {
154
            return "c1";
155
        }
156
        if ($this->c2 != null) {
157
            return "c2";
158
        }
159
        return null;
160
    }
161
162
    /**
163
     * Check if we are able to fill the parent fight or not
164
     * If one of the children has c1 x c2, then we must wait to fill parent
165
     *
166
     * @return bool
167
     */
168 View Code Duplication
    public function hasDeterminedParent()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
169
    {
170
        if ($this->has2Fighters()) return true;
171
        foreach ($this->group->children as $child) {
172
            $fight = $child->fights->get(0);
173
            if ($fight->has2Fighters()) return false;
174
        }
175
        return true;
176
    }
177
178
    public function shouldBeInFightList()
179
    {
180
        if ($this->belongsToFirstRound() && $this->dontHave2Fighters()) return false;
181
        if ($this->has2Fighters()) return true;
182
        // We aint in the first round, and there is 1 or 0 competitor
183
        // We check children, and see :
184
        // if there is 2  - 2 fighters -> undetermine, we cannot add it to fight list
185
        // if there is 2  - 1 fighters -> undetermine, we cannot add it to fight list
186
        // if there is 2  - 0 fighters -> undetermine, we cannot add it to fight list
187
        // if there is 1  - 2 fighters -> undetermine, we cannot add it to fight list
188
        // if there is 1  - 1 fighters -> fight should have 2 fighters, undetermines
189
        // if there is 1  - 0 fighters -> determined, fight should not be in the list
190
        // if there is 0  - 1 fighters -> determined, fight should not be in the list
191
        // So anyway, we should return false
192
        return false;
193
    }
194
195
    /**
196
     * return true if fight has 2 fighters ( No BYE )
197
     * @return bool
198
     */
199
    private function has2Fighters(): bool
200
    {
201
        return $this->c1 != null && $this->c2 != null;
202
    }
203
204
    private function belongsToFirstRound()
205
    {
206
        $firstRoundFights = $this->group->championship->firstRoundFights->pluck('id')->toArray();
207
        if (in_array($this->id, $firstRoundFights)) return true;
208
        return false;
209
    }
210
211
    private function dontHave2Fighters() // 1 or 0
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
212
    {
213
        return $this->c1 == null || $this->c2 == null;
214
    }
215
216
217
    public static function generateFightsId($championship)
218
    {
219
        $order = 1;
220
        foreach ($championship->fights as $fight) {
221
            $order = $fight->updateShortId($order);
222
        }
223
    }
224
225
    /**
226
     * @param $order
227
     * @return int
228
     */
229
    public function updateShortId($order)
230
    {
231
        if ($this->shouldBeInFightList()) {
232
            $this->short_id = $order;
233
            $this->save();
234
            return ++$order;
235
        }
236
        return $order;
237
    }
238
239
}