Completed
Push — master ( c3f0f6...0c6e4d )
by Tomáš
02:30
created

WithTeams::getRealTeamCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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

59
			/** @scrutinizer ignore-call */ 
60
   $wheres = $this->getRounds();
Loading history...
60
		}
61
62 29
		$teams = $this->getTeams();
63 29
		shuffle($teams);
64
65 29
		while (count($teams) > 0) {
66 29
			foreach ($wheres as $where) {
67 29
				if (count($teams) > 0) {
68 29
					$where->addTeam(array_shift($teams));
69
				}
70
			}
71
		}
72 29
		foreach ($wheres as $where) {
73 29
			$where->splitTeams();
74
		}
75 29
		return $this;
76
	}
77
78
	/**
79
	 * Get all teams in the object
80
	 *
81
	 * @param bool                        $ordered  If true - order the teams by their score/points
82
	 * @param string|null                 $ordering What to order the teams by - Constants::POINTS, Constants::SCORE
83
	 * @param TeamFilter[]|TeamFilter[][] $filters  Filters to filter the returned teams (ex. if you only want to get the first 3 teams)
84
	 *
85
	 * @return Team[]
86
	 * @throws Exception
87
	 */
88 102
	public function getTeams(bool $ordered = false, ?string $ordering = Constants::POINTS, array $filters = []) : array {
89 102
		if (is_null($ordering)) {
90 25
			$ordering = Constants::POINTS;
91
		}
92 102
		if ($ordered) {
93 3
			$returnTeams = $this->sortTeams($ordering);
94
		}
95
		else {
96 102
			$returnTeams = $this->teams->unique()->get();
97
		}
98
99
		// APPLY FILTERS
100 102
		if (count($filters) > 0) {
101 25
			$this->filterTeams($returnTeams, $filters);
102
		}
103
104 96
		return $returnTeams;
105
	}
106
107
	/**
108
	 * Sort the teams by their score/points
109
	 *
110
	 * @param string|null                 $ordering What to order the teams by - Constants::POINTS, Constants::SCORE
111
	 * @param TeamFilter[]|TeamFilter[][] $filters  Filters to filter the returned teams (ex. if you only want to get the first 3 teams)
112
	 *
113
	 * @return Team[]
114
	 * @throws Exception
115
	 */
116 48
	public function sortTeams(?string $ordering = Constants::POINTS, array $filters = []) : array {
117 48
		if (is_null($ordering)) {
118 37
			$ordering = Constants::POINTS;
119
		}
120 48
		$sorter = new TeamSorter($this->getContainer(), $ordering);
1 ignored issue
show
Bug introduced by
It seems like getContainer() 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

120
		$sorter = new TeamSorter($this->/** @scrutinizer ignore-call */ getContainer(), $ordering);
Loading history...
121 48
		$teams = $this->teams->addSorter($sorter)->unique()->get();
122
123
		// APPLY FILTERS
124 48
		if (count($filters) > 0) {
125 7
			$this->filterTeams($teams, $filters);
126
		}
127
128 48
		return $teams;
129
	}
130
131
	/**
132
	 * Filter teams using the specified filters
133
	 *
134
	 * @param array                       $teams   Teams to filter through
135
	 * @param TeamFilter[]|TeamFilter[][] $filters Filters to use
136
	 *
137
	 * @return array
138
	 * @throws Exception
139
	 */
140 29
	public function filterTeams(array &$teams, array $filters) : array {
141
		// APPLY FILTERS
142 29
		if ($this instanceof WithGroupsInterface) {
143 5
			$filter = new Filter($filters, $this->getGroups());
144 5
			$filter->filter($teams);
145
		}
146 27
		else if ($this instanceof Group) {
147 27
			$filter = new Filter($filters, [$this]);
148 27
			$filter->filter($teams);
149
		}
150 23
		return $teams;
151
	}
152
153
	/**
154
	 * Add one or more teams into the object.
155
	 *
156
	 * @param Team ...$teams Team objects
157
	 *
158
	 * @return WithTeamsInterface
159
	 */
160 34
	public function addTeam(Team ...$teams) : WithTeamsInterface {
161 34
		foreach ($teams as $team) {
162 34
			$this->teams->insert($team);
163
		}
164 34
		return $this;
165
	}
166
167
	/**
168
	 * Get the container for games
169
	 *
170
	 * @return TeamContainer
171
	 */
172 64
	public function getTeamContainer() : TeamContainer {
173 64
		return $this->teams;
174
	}
175
176
	/**
177
	 * Add a child container for games
178
	 *
179
	 * @param TeamContainer $container
180
	 *
181
	 * @return WithTeamsInterface
182
	 */
183 64
	public function addTeamContainer(TeamContainer $container) : WithTeamsInterface {
184 64
		$this->teams->addChild($container);
185 64
		return $this;
186
	}
187
}