Completed
Push — master ( cf6760...1f6d44 )
by Julien
02:39
created

FightersGroup::syncTeams()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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