Passed
Push — master ( 1565da...84ef8e )
by Julien
71:23 queued 12:22
created

FightersGroup::generateNextRoundsFights()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 11
rs 9.4285
cc 2
eloc 7
nc 2
nop 1
1
<?php
2
3
namespace Xoco70\KendoTournaments\Models;
4
5
use Carbon\Carbon;
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Support\Collection;
8
use Illuminate\Support\Facades\DB;
9
use Kalnoy\Nestedset\NodeTrait;
10
use Xoco70\KendoTournaments\TreeGen\TreeGen;
11
12
class FightersGroup extends Model
13
{
14
    protected $table = 'fighters_groups';
15
    public $timestamps = true;
16
    protected $guarded = ['id'];
17
18
    use NodeTrait;
19
20
    /**
21
     * Check if Request contains tournamentSlug / Should Move to TreeRequest When Built.
22
     *
23
     * @param $request
24
     *
25
     * @return bool
26
     */
27
    public static function hasTournamentInRequest($request)
28
    {
29
        return $request->tournament != null;
30
    }
31
32
    /**
33
     * Check if Request contains championshipId / Should Move to TreeRequest When Built.
34
     *
35
     * @param $request
36
     *
37
     * @return bool
38
     */
39
    public static function hasChampionshipInRequest($request)
40
    {
41
        return $request->championshipId != null; // has return false, don't know why
42
    }
43
44
    /**
45
     * @param Championship $championship
46
     * @param $fightsByRound
47
     */
48
    private static function updateParentFight(Championship $championship, $fightsByRound)
49
    {
50
        foreach ($fightsByRound as $fight) {
51
            $parentGroup = $fight->group->parent;
52
            if ($parentGroup == null) break;
53
            $parentFight = $parentGroup->fights->get(0); //TODO This Might change when extending to Preliminary
54
55
            // IN this $fight, is c1 or c2 has the info?
56
            if ($championship->isDirectEliminationType()) {
57
                // determine whether c1 or c2 must be updated
58
                self::chooseAndUpdateParentFight($fight, $parentFight);
59
            }
60
        }
61
    }
62
63
    /**
64
     * @param $fight
65
     * @param $parentFight
66
     */
67
    private static function chooseAndUpdateParentFight($fight, $parentFight)
68
    {
69
        $fighterToUpdate = $fight->getParentFighterToUpdate();
70
        $valueToUpdate = $fight->getValueToUpdate();
71
        // we need to know if the child has empty fighters, is this BYE or undetermined
72
        if ($fight->hasDeterminedParent() && $valueToUpdate != null) {
73
            $parentFight->$fighterToUpdate = $fight->$valueToUpdate;
74
            $parentFight->save();
75
        }
76
    }
77
78
    /**
79
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
80
     */
81
    public function championship()
82
    {
83
        return $this->belongsTo(Championship::class);
84
    }
85
86
    /**
87
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
88
     */
89
    public function fights()
90
    {
91
        return $this->hasMany(Fight::class);
92
    }
93
94
    public function teams()
95
    {
96
        return $this->belongsToMany(Team::class, 'fighters_group_team')->withTimestamps();
97
    }
98
99
    public function competitors()
100
    {
101
        return $this->belongsToMany(Competitor::class, 'fighters_group_competitor')->withTimestamps();
102
    }
103
104
    /**
105
     * Generate First Round Fights
106
     * @param Championship $championship
107
     */
108
    public static function generateFights(Championship $championship)
109
    {
110
        $settings = $championship->getSettings();
111
        // Delete previous fight for this championship
112
113
        $arrGroupsId = $championship->fightersGroups()->get()->pluck('id');
114
115
        Fight::destroy($arrGroupsId);
116
117
        if ($settings->hasPreliminary && $settings->preliminaryGroupSize == 3) {
118
            for ($numGroup = 1; $numGroup <= $settings->preliminaryGroupSize; $numGroup++) {
119
                Fight::savePreliminaryFightGroup($championship->fightersGroups()->get(), $numGroup);
120
            }
121
        } else {
122
            Fight::saveGroupFights($championship);
123
        }
124
    }
125
126
    /**
127
     * Supercharge of sync Many2Many function.
128
     * Original sync doesn't insert NULL ids.
129
     *
130
     * @param $fighters
131
     */
132
    public function syncTeams($fighters)
133
    {
134
        $this->teams()->detach();
135
        foreach ($fighters as $fighter) {
136
            if ($fighter != null) {
137
                $this->teams()->attach($fighter);
138
            } else {
139
                // Insert row manually
140
                DB::table('fighters_group_team')->insertGetId(
141
                    ['team_id' => null, 'fighters_group_id' => $this->id]
142
                );
143
            }
144
        }
145
    }
146
147
    /**
148
     * Supercharge of sync Many2Many function.
149
     * Original sync doesn't insert NULL ids.
150
     *
151
     * @param $fighters
152
     */
153
    public function syncCompetitors($fighters)
154
    {
155
        $this->competitors()->detach();
156
        foreach ($fighters as $fighter) {
157
            if ($fighter != null) {
158
                $this->competitors()->attach($fighter);
159
            } else {
160
                DB::table('fighters_group_competitor')->insertGetId(
161
                    ['competitor_id' => null, 'fighters_group_id' => $this->id,
162
                        "created_at" => Carbon::now(),
163
                        "updated_at" => Carbon::now(),
164
                    ]
165
                );
166
            }
167
        }
168
    }
169
170
171
    /**
172
     * Get the many 2 many relationship with
173
     *
174
     * @return Collection
175
     */
176
    public function competitorsWithNull(): Collection
177
    {
178
        $competitors = new Collection();
179
        $fgcs = FighterGroupCompetitor::where('fighters_group_id', $this->id)
180
            ->with('competitor')
181
            ->get();
182
        foreach ($fgcs as $fgc) {
183
            $competitors->push($fgc->competitor ?? new Competitor());
184
        }
185
186
        return $competitors;
187
188
    }
189
190
191
    public function teamsWithNull(): Collection
192
    {
193
        $teams = new Collection();
194
        $fgcs = FighterGroupTeam::where('fighters_group_id', $this->id)
195
            ->with('team')
196
            ->get();
197
        foreach ($fgcs as $fgc) {
198
            $teams->push($fgc->team ?? new Team());
199
        }
200
201
        return $teams;
202
203
    }
204
205
    public function getFighters(): Collection
206
    {
207
        if ($this->championship->category->isTeam()) {
208
            return $this->teamsWithNull();
209
        }
210
        return $this->competitorsWithNull();
211
212
    }
213
214
    public static function getBaseNumGroups($initialGroupId, $numGroups, $numRound): int
215
    {
216
        $parentId = $initialGroupId;
217
218
        for ($i = 1; $i <= $numRound; $i++) {
219
            $parentId += $numGroups / $numRound;
220
        }
221
222
        return $parentId;
223
    }
224
225
    /**
226
     *
227
     * @param Championship $championship
228
     */
229
    public static function generateNextRoundsFights(Championship $championship)
230
    {
231
        $championship = $championship->withCount('teams', 'competitors')->first();
232
        $fightersCount = $championship->competitors_count + $championship->teams_count;
233
        $maxRounds = intval(ceil(log($fightersCount, 2)));
234
        for ($numRound = 1; $numRound < $maxRounds; $numRound++) {
235
            $fightsByRound = $championship->fightsByRound($numRound)->with('group.parent', 'group.children')->get();
236
            self::updateParentFight($championship, $fightsByRound);
237
        }
238
239
    }
240
241
    /**
242
     * @return string
243
     */
244
    public function getFighterType()
245
    {
246
        if ($this->championship->category->isTeam()) {
247
            return Team::class;
248
        }
249
        return Competitor::class;
250
    }
251
}
252