Completed
Branch master (0e4a87)
by Tomáš
03:29 queued 01:30
created

Group::__construct()   B

Complexity

Conditions 11
Paths 11

Size

Total Lines 26
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 11
eloc 25
nc 11
nop 1
dl 0
loc 26
rs 7.3166
c 1
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace TournamentGenerator;
4
5
/**
6
 *
7
 */
8
class Group
9
{
10
11
	private $generator = null;
12
	private $teams = []; // ARRAY OF TEAMS
13
	private $progressed = []; // ARRAY OF TEAMS ALREADY PROGRESSED FROM THIS GROUP
14
	public $name = ''; // DISPLAYABLE NAME
15
	private /** @scrutinizer ignore-all */ $ordering = POINTS; // WHAT TO DECIDE ON WHEN ORDERING TEAMS
1 ignored issue
show
Bug introduced by
The constant TournamentGenerator\POINTS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
16
	private $progressions = []; // ARRAY OF PROGRESSION CONDITION OBJECTS
17
	private $games = []; // ARRAY OF GAME OBJECTS
18
	public $id = ''; // UNIQID OF GROUP FOR IDENTIFICATIONT
19
	public $winPoints = 3; // POINTS AQUIRED FROM WINNING
20
	public $drawPoints = 1; // POINTS AQUIRED FROM DRAW
21
	public $lostPoints = 0; // POINTS AQUIRED FROM LOOSING
22
	public $secondPoints = 2; // POINTS AQUIRED FROM BEING SECOND (APPLIES ONLY FOR 3 OR 4 INGAME VALUE)
23
	public $thirdPoints = 1; // POINTS AQUIRED FROM BEING THIRD (APPLIES ONLY FOR 4 INGAME VALUE)
24
	public $progressPoints = 50; // POINTS AQUIRED FROM PROGRESSING TO THE NEXT ROUND
25
	public $order = 0; // ORDER OF GROUPS IN ROUND
26
27
	function __construct(array $settings = []) {
28
		$this->id = uniqid();
29
		$this->generator = new Generator($this);
30
		foreach ($settings as $key => $value) {
31
			switch ($key) {
32
				case 'name':
33
					if (gettype($value) !== 'string') throw new \Exception('Expected string as group name '.gettype($value).' given');
34
					$this->name = $value;
35
					break;
36
				case 'type':
37
					$this->generator->setType($value);
38
					break;
39
				case 'ordering':
40
					if (!in_array($value, orderingTypes)) throw new \Exception('Unknown group ordering: '.$value);
41
					$this->ordering = $value;
42
					break;
43
				case 'inGame':
44
					$this->generator->setInGame($value);
45
					break;
46
				case 'maxSize':
47
					$value = (int) $value;
48
					if ($value > 1) $this->generator->setMaxSize($value);
49
					break;
50
				case 'order':
51
					$this->order = (int) $value;
52
					break;
53
			}
54
		}
55
	}
56
	function __toString() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
57
		return 'Group '.$this->name;
58
	}
59
60
	public function allowSkip(){
61
		$this->generator->allowSkip();
62
		return $this;
63
	}
64
	public function disallowSkip(){
65
		$this->generator->disallowSkip();
66
		return $this;
67
	}
68
	public function setSkip(bool $skip) {
69
		$this->generator->setSkip($skip);
70
		return $this;
71
	}
72
	public function getSkip() {
73
		return $this->generator->getSkip();
74
	}
75
76
	public function addTeam(...$teams) {
77
		foreach ($teams as $team) {
78
			if ($team instanceof Team)  {
79
				$this->teams[] = $team;
80
				$team->groupResults[$this->id] = [
81
					'group' => $this,
82
					'points' => 0,
83
					'score'  => 0,
84
					'wins'   => 0,
85
					'draws'  => 0,
86
					'losses' => 0,
87
					'second' => 0,
88
					'third'  => 0
89
				];
90
			}
91
			elseif (gettype($team) === 'array') {
92
				foreach ($team as $team2) {
93
					if ($team2 instanceof Team) $this->teams[] = $team2;
94
					$team2->groupResults[$this->id] = [
95
						'group' => $this,
96
						'points' => 0,
97
						'score'  => 0,
98
						'wins'   => 0,
99
						'draws'  => 0,
100
						'losses' => 0,
101
						'second' => 0,
102
						'third'  => 0
103
					];
104
				}
105
			}
106
			else throw new \Exception('Trying to add team which is not an instance of Team class');
107
		}
108
		return $this;
109
	}
110
	public function getTeams($filters = []) {
111
		$teams = $this->teams;
112
113
		if (gettype($filters) !== 'array' && $filters instanceof TeamFilter) $filters = [$filters];
114
		elseif (gettype($filters) !== 'array') $filters = [];
115
116
		// APPLY FILTERS
117
		foreach ($filters as $key => $filter) {
118
			if (gettype($filter) === 'array') {
119
				switch (strtolower($key)) {
120
					case 'and':
121
						foreach ($teams as $tkey => $team) {
122
							if (!$this->filterAnd($team, $filter)) unset($teams[$tkey]); // IF FILTER IS NOT VALIDATED REMOVE TEAM FROM RETURN ARRAY
123
						}
124
						break;
125
					case 'or':
126
						foreach ($teams as $tkey => $team) {
127
							if (!$this->filterOr($team, $filter)) unset($teams[$tkey]); // IF FILTER IS NOT VALIDATED REMOVE TEAM FROM RETURN ARRAY
128
						}
129
						break;
130
					default:
131
						throw new \Exception('Unknown opperand type "'.$key.'". Expected "and" or "or".');
132
						break;
133
				}
134
			}
135
			elseif ($filter instanceof TeamFilter) {
136
				foreach ($teams as $tkey => $team) {
137
					if (!$filter->validate($team, $this->id, 'sum', $this)) {
138
						unset($teams[$tkey]); // IF FILTER IS NOT VALIDATED REMOVE TEAM FROM RETURN ARRAY
139
					}
140
				}
141
			}
142
			else {
143
				throw new \Exception('Filer ['.$key.'] is not an instance of TeamFilter class');
144
			}
145
		}
146
		return $teams;
147
	}
148
	public function team(string $name = '') {
149
		$t = new Team($name);
150
		$this->teams[] = $t;
151
		$t->groupResults[$this->id] = [
152
			'group' => $this,
153
			'points' => 0,
154
			'score'  => 0,
155
			'wins'   => 0,
156
			'draws'  => 0,
157
			'losses' => 0,
158
			'second' => 0,
159
			'third'  => 0
160
		];
161
		return $t;
162
	}
163
	public function sortTeams($filters = [], $ordering = null) {
164
		if (!isset($ordering)) $ordering = $this->ordering;
165
		switch ($ordering) {
166
			case POINTS:{
1 ignored issue
show
Bug introduced by
The constant TournamentGenerator\POINTS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
167
				usort($this->teams, function($a, $b) {
168
					if ($a->groupResults[$this->id]["points"] === $b->groupResults[$this->id]["points"] && $a->groupResults[$this->id]["score"] === $b->groupResults[$this->id]["score"]) return 0;
169
					if ($a->groupResults[$this->id]["points"] === $b->groupResults[$this->id]["points"]) return ($a->groupResults[$this->id]["score"] > $b->groupResults[$this->id]["score"] ? -1 : 1);
170
					return ($a->groupResults[$this->id]["points"] > $b->groupResults[$this->id]["points"] ? -1 : 1);
171
				});
172
				break;}
173
			case SCORE:{
1 ignored issue
show
Bug introduced by
The constant TournamentGenerator\SCORE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
174
				usort($this->teams, function($a, $b) {
175
					if ($a->groupResults[$this->id]["score"] === $b->groupResults[$this->id]["score"]) return 0;
176
					return ($a->groupResults[$this->id]["score"] > $b->groupResults[$this->id]["score"] ? -1 : 1);
177
				});
178
				break;}
179
		}
180
		return $this->getTeams($filters);
181
	}
182
183
	public function filterAnd(Team $team, array $filters) {
184
		foreach ($filters as $key => $value) {
185
			if (gettype($value) === 'array') {
186
				switch (strtolower($key)) {
187
					case 'and':
188
						if ($this->filterAnd($team, $value)) return false;
189
						break;
190
					case 'or':
191
						if ($this->filterOr($team, $value)) return false;
192
						break;
193
					default:
194
						throw new \Exception('Unknown opperand type "'.$key.'". Expected "and" or "or".');
195
						break;
196
				}
197
			}
198
			elseif ($value instanceof TeamFilter) {
199
				if (!$value->validate($team, $this->id, 'sum', $this)) return false;
200
			}
201
			else {
202
				throw new \Exception('Filer ['.$key.'] is not an instance of TeamFilter class');
203
			}
204
		}
205
		return true;
206
	}
207
	public function filterOr(Team $team, array $filters) {
208
		foreach ($filters as $key => $value) {
209
			if (gettype($value) === 'array') {
210
				switch (strtolower($key)) {
211
					case 'and':
212
						if ($this->filterAnd($team, $value)) return true;
213
						break;
214
					case 'or':
215
						if ($this->filterOr($team, $value)) return true;
216
						break;
217
					default:
218
						throw new \Exception('Unknown opperand type "'.$key.'". Expected "and" or "or".');
219
						break;
220
				}
221
			}
222
			elseif ($value instanceof TeamFilter) {
223
				if (!$value->validate($team, $this->id, 'sum', $this)) return true;
224
			}
225
			else {
226
				throw new \Exception('Filer ['.$key.'] is not an instance of TeamFilter class');
227
			}
228
		}
229
		return false;
230
	}
231
232
	public function setType(string $type = R_R) {
1 ignored issue
show
Bug introduced by
The constant TournamentGenerator\R_R was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
233
		$this->generator->setType($type);
234
		return $this;
235
	}
236
	public function getType() {
237
		return $this->generator->getType();
238
	}
239
240
	public function setOrdering(string $ordering = POINTS) {
1 ignored issue
show
Bug introduced by
The constant TournamentGenerator\POINTS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
241
		if (in_array($ordering, orderingTypes)) $this->ordering = $ordering;
242
		else throw new \Exception('Unknown group ordering: '.$ordering);
243
		return $this;
244
	}
245
	public function getOrdering() {
246
		return $this->ordering;
247
	}
248
249
	public function setInGame(int $inGame) {
250
		$this->generator->setInGame($inGame);
251
		return $this;
252
	}
253
	public function getInGame() {
254
		return $this->generator->getInGame();
255
	}
256
257
	public function addProgression(Progression $progression) {
258
		$this->progressions[] = $progression;
259
		return $this;
260
	}
261
	public function progression(Group $to, int $start = 0, int $len = null) {
262
		$p = new Progression($this, $to, $start, $len);
263
		$this->progressions[] = $p;
264
		return $p;
265
	}
266
	public function progress(bool $blank = false) {
267
		foreach ($this->progressions as $progression) {
268
			$progression->progress($blank);
269
		}
270
	}
271
	public function addProgressed(...$teams) {
272
		foreach ($teams as $team) {
273
			if ($team instanceOf Team) {
274
				$this->progressed[] = $team->id;
275
			}
276
			elseif (gettype($team) === 'string' || gettype($team) === 'integer') {
277
				$this->progressed[] = $team;
278
			}
279
			elseif (gettype($team) === 'array') {
280
				foreach ($team as $teamInner) {
281
					if ($teamInner instanceOf Team) {
282
						$this->progressed[] = $teamInner->id;
283
					}
284
					elseif (gettype($teamInner) === 'string' || gettype($teamInner) === 'integer') {
285
						$this->progressed[] = $teamInner;
286
					}
287
				}
288
			}
289
		}
290
		return $this;
291
	}
292
	public function isProgressed(Team $team) {
293
		if (in_array($team->id, $this->progressed)) {
294
			return true;
295
		}
296
		return false;
297
	}
298
299
	public function genGames() {
300
		$this->generator->genGames();
301
		return $this->games;
302
	}
303
304
	public function game(array $teams = []) {
305
		$g = new Game($teams, $this);
306
		$this->games[] = $g;
307
		return $g;
308
	}
309
	public function addGame(...$games){
310
		foreach ($games as $key => $game) {
311
			if (gettype($game) === 'array') {
312
				unset($games[$key]);
313
				$games = array_merge($games, $game);
314
			}
315
		}
316
		foreach ($games as $game) {
317
			if ($game instanceof Game) $this->games[] = $game;
318
			else throw new \Exception('Trying to add game which is not instance of Game object.');
319
		}
320
		return $this;
321
	}
322
	public function getGames() {
323
		return $this->games;
324
	}
325
	public function orderGames() {
326
		if (count($this->games) <= 4) return $this->games;
327
		$this->games = $this->generator->orderGames();
328
		return $this->games;
329
	}
330
331
	public function simulate($filters = [], bool $reset = true) {
332
		foreach ($this->getGames() as $game) {
333
			$teams = $game->getTeams();
334
			$results = [];
335
			foreach ($teams as $team) {
336
				$results[$team->id] = floor(rand(-1000, 5000));
337
			}
338
			$game->setResults($results);
339
		}
340
		$return = $this->sortTeams($filters);
341
		if (!$reset) return $return;
342
		foreach ($this->getGames() as $game) {
343
			$game->resetResults();
344
		}
345
		return $return;
346
	}
347
	public function resetGames() {
348
		foreach ($this->getGames() as $game) {
349
			if (isset($game)) $game->resetResults();
350
		}
351
		return $this;
352
	}
353
	public function isPlayed(){
354
		foreach ($this->games as $game) {
355
			if ((isset($game) || !$this->getSkip()) && !$game->isPlayed()) return false;
356
		}
357
		return true;
358
	}
359
360
}
361