Completed
Push — master ( f8ef69...cf6760 )
by Julien
02:41
created

FightersGroup::fights()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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