Passed
Push — master ( 228718...2540c1 )
by Tomáš
09:08
created

WithTeams::isSeeded()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 4
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 3
rs 10
1
<?php
2
3
4
namespace TournamentGenerator\Traits;
5
6
use Exception;
7
use TournamentGenerator\Constants;
8
use TournamentGenerator\Containers\TeamContainer;
9
use TournamentGenerator\Group;
10
use TournamentGenerator\Helpers\Filter;
11
use TournamentGenerator\Helpers\Functions;
12
use TournamentGenerator\Helpers\Sorter\TeamSorter;
13
use TournamentGenerator\Interfaces\WithGroups as WithGroupsInterface;
14
use TournamentGenerator\Interfaces\WithTeams as WithTeamsInterface;
15
use TournamentGenerator\Round;
16
use TournamentGenerator\Team;
17
use TournamentGenerator\TeamFilter;
18
19
/**
20
 * Trait WithTeams
21
 *
22
 * @package TournamentGenerator\Traits
23
 * @author  Tomáš Vojík <[email protected]>
24
 * @since   0.4
25
 */
26
trait WithTeams
27
{
28
29
	/** @var TeamContainer Teams in a object */
30
	protected TeamContainer $teams;
31
32
	/**
33
	 * Create a new team and add it into the object
34
	 *
35
	 * @param string          $name Name of the new team
36
	 * @param string|int|null $id   Id of the new team - if omitted -> it is generated automatically as unique string
37
	 *
38
	 * @return Team Newly created team
39
	 * @throws Exception
40
	 */
41 117
	public function team(string $name = '', $id = null) : Team {
42 117
		$t = new Team($name, $id);
43 117
		$this->teams->insert($t);
44 117
		return $t;
45
	}
46
47
	/**
48
	 * Split teams into its Groups
49
	 *
50
	 * @param Round ...$wheres
51
	 *
52
	 * @return $this
53
	 * @throws Exception
54
	 * @noinspection CallableParameterUseCaseInTypeContextInspection
55
	 */
56 31
	public function splitTeams(Round ...$wheres) : WithTeamsInterface {
57 31
		if (count($wheres) === 0) {
58 8
			$wheres = $this->getRounds();
0 ignored issues
show
Bug introduced by
It seems like getRounds() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

58
			/** @scrutinizer ignore-call */ 
59
   $wheres = $this->getRounds();
Loading history...
59
		}
60
61 31
		$teams = $this->getTeams(true, Constants::SEED);
62 31
		if ($this::isSeeded($teams)) {
63 2
			Functions::sortAlternate($teams);
64
		}
65
		else {
66 29
			shuffle($teams);
67
		}
68
69 31
		$split = ceil(count($teams) / count($wheres));
70 31
		foreach ($wheres as $where) {
71 31
			if (count($teams) > 0) {
72 31
				$where->addTeam(...array_splice($teams, 0, $split));
0 ignored issues
show
Bug introduced by
$split of type double is incompatible with the type integer|null expected by parameter $length of array_splice(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

72
				$where->addTeam(...array_splice($teams, 0, /** @scrutinizer ignore-type */ $split));
Loading history...
73
			}
74
		}
75 31
		foreach ($wheres as $where) {
76 31
			$where->splitTeams();
77
		}
78 31
		return $this;
79
	}
80
81
	/**
82
	 * Get all teams in the object
83
	 *
84
	 * @param bool                        $ordered  If true - order the teams by their score/points
85
	 * @param string|null                 $ordering What to order the teams by - Constants::POINTS, Constants::SCORE
86
	 * @param TeamFilter[]|TeamFilter[][] $filters  Filters to filter the returned teams (ex. if you only want to get the first 3 teams)
87
	 *
88
	 * @return Team[]
89
	 * @throws Exception
90
	 */
91 122
	public function getTeams(bool $ordered = false, ?string $ordering = Constants::POINTS, array $filters = []) : array {
92 122
		if (is_null($ordering)) {
93 25
			$ordering = Constants::POINTS;
94
		}
95 122
		if ($ordered) {
96 40
			$returnTeams = $this->sortTeams($ordering);
97
		}
98
		else {
99 121
			$returnTeams = $this->teams->unique()->get();
100
		}
101
102
		// APPLY FILTERS
103 122
		if (count($filters) > 0) {
104 25
			$this->filterTeams($returnTeams, $filters);
105
		}
106
107 116
		return $returnTeams;
108
	}
109
110
	/**
111
	 * Sort the teams by their score/points
112
	 *
113
	 * @param string|null                 $ordering What to order the teams by - Constants::POINTS, Constants::SCORE
114
	 * @param TeamFilter[]|TeamFilter[][] $filters  Filters to filter the returned teams (ex. if you only want to get the first 3 teams)
115
	 *
116
	 * @return Team[]
117
	 * @throws Exception
118
	 */
119 58
	public function sortTeams(?string $ordering = Constants::POINTS, array $filters = []) : array {
120 58
		if (is_null($ordering)) {
121 37
			$ordering = Constants::POINTS;
122
		}
123 58
		$sorter = new TeamSorter($this->getContainer(), $ordering);
124 58
		$teams = $this->teams->addSorter($sorter)->unique()->get();
125
126
		// APPLY FILTERS
127 58
		if (count($filters) > 0) {
128 7
			$this->filterTeams($teams, $filters);
129
		}
130
131 58
		return $teams;
132
	}
133
134
	/**
135
	 * Filter teams using the specified filters
136
	 *
137
	 * @param array                       $teams   Teams to filter through
138
	 * @param TeamFilter[]|TeamFilter[][] $filters Filters to use
139
	 *
140
	 * @return array
141
	 * @throws Exception
142
	 */
143 29
	public function filterTeams(array &$teams, array $filters) : array {
144
		// APPLY FILTERS
145 29
		if ($this instanceof WithGroupsInterface) {
146 5
			$filter = new Filter($filters, $this->getGroups());
147 5
			$filter->filter($teams);
148
		}
149 27
		else if ($this instanceof Group) {
150 27
			$filter = new Filter($filters, [$this]);
151 27
			$filter->filter($teams);
152
		}
153 23
		return $teams;
154
	}
155
156
	/**
157
	 * @param Team[] $teams
158
	 *
159
	 * @return bool
160
	 */
161 37
	public static function isSeeded(array $teams) : bool {
162 37
		foreach ($teams as $team) {
163 37
			if ($team->getSeed() > 0) {
164 2
				return true;
165
			}
166
		}
167 35
		return false;
168
	}
169
170
	/**
171
	 * Add one or more teams into the object.
172
	 *
173
	 * @param Team ...$teams Team objects
174
	 *
175
	 * @return WithTeamsInterface
176
	 * @throws Exception
177
	 */
178 45
	public function addTeam(Team ...$teams) : WithTeamsInterface {
179 45
		foreach ($teams as $team) {
180 45
			$this->teams->insert($team);
181
		}
182 45
		return $this;
183
	}
184
185
	/**
186
	 * Get the container for games
187
	 *
188
	 * @return TeamContainer
189
	 */
190 162
	public function getTeamContainer() : TeamContainer {
191 162
		return $this->teams;
192
	}
193
194
	/**
195
	 * Add a child container for games
196
	 *
197
	 * @param TeamContainer $container
198
	 *
199
	 * @return WithTeamsInterface
200
	 * @throws Exception
201
	 */
202 158
	public function addTeamContainer(TeamContainer $container) : WithTeamsInterface {
203 158
		$this->teams->addChild($container);
204 158
		return $this;
205
	}
206
}