Completed
Push — master ( 676495...4dafdb )
by Guillermo
9s
created

PlayersCollection::excludePlayers()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 9
cts 9
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 6
nc 4
nop 1
crap 4
1
<?php
2
3
namespace SecretSanta;
4
5
use SecretSanta\Exceptions\PlayersCollectionException;
6
7
/**
8
 * Class PlayersCollection
9
 * @package SecretSanta
10
 */
11
class PlayersCollection implements \Countable
12
{
13
    /** @var Player[] */
14
    private $players = [];
15
    /** @var array  */
16
    private $excludePlayers = [];
17
18
    /**
19
     * @param Player $player
20
     * @throws PlayersCollectionException
21
     */
22 9
    public function addPlayer(Player $player)
23
    {
24 9
        if (!$this->isDuplicatePlayer($player)) {
25 9
            $this->players[$player->id()] = $player;
26 9
        }
27 9
    }
28
29
    /**
30
     * @param Player $player
31
     * @param Player $couple
32
     * @throws PlayersCollectionException
33
     */
34 16
    public function addCouple(Player $player, Player $couple)
35
    {
36 16
        if (!$this->areDifferentPlayers($player, $couple)) {
37 2
            throw  new PlayersCollectionException('The couple can not be the same player');
38
        }
39
40 14
        if (!$this->isDuplicatePlayer($player) && !$this->isDuplicatePlayer($couple) ) {
41 13
            $this->players[$player->id()] = $player;
42 13
            $this->players[$couple->id()] = $couple;
43
44 13
            $this->excludePlayers($player, $couple);
45 13
        }
46 13
    }
47
48
    /**
49
     * @return Player[]
50
     */
51 11
    public function players()
52
    {
53 11
        return $this->players;
54
    }
55
56
    /**
57
     * @return Player[]
58
     */
59 9
    public function shufflePlayers()
60
    {
61 9
        return $this->shuffleAssoc($this->players);
62
    }
63
64
    /**
65
     * @param string $id
66
     * @return Player
67
     * @throws PlayersCollectionException
68
     */
69 11
    public function player($id)
70
    {
71 11
        if (!isset($this->players[$id])) {
72 1
            throw new PlayersCollectionException("Player {$id} not found");
73
        }
74
75 10
        return $this->players[$id];
76
    }
77
78
79
    /**
80
     * @param Player[] ...$players
81
     */
82 13
    private function excludePlayers(...$players)
83
    {
84 13
        foreach ($players as $mainPlayer) {
85 13
            foreach ($players as $player) {
86 13
                if ($mainPlayer->id() == $player->id()){
0 ignored issues
show
Bug introduced by
The method id cannot be called on $mainPlayer (of type array<integer,object<SecretSanta\Player>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Bug introduced by
The method id cannot be called on $player (of type array<integer,object<SecretSanta\Player>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
87 13
                    continue;
88
                }
89 13
                $this->excludePlayers[$mainPlayer->id()][] = $player->id();
0 ignored issues
show
Bug introduced by
The method id cannot be called on $mainPlayer (of type array<integer,object<SecretSanta\Player>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Bug introduced by
The method id cannot be called on $player (of type array<integer,object<SecretSanta\Player>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
90 13
            }
91 13
        }
92 13
    }
93
94
    /**
95
     * @param Player $player
96
     * @param Player $player2
97
     * @return bool
98
     */
99 9
    public function areExclude(Player $player, Player $player2)
100
    {
101 9
        if (array_key_exists($player->id(), $this->excludePlayers)
102 9
            && in_array($player2->id(), $this->excludePlayers[$player->id()])
103 9
        ) {
104 6
            return true;
105
        }
106
107 9
        return false;
108
    }
109
110
    /**
111
     * @return int
112
     */
113 9
    public function count()
114
    {
115 9
        return count($this->players);
116
    }
117
118
    /**
119
     * @return int
120
     */
121 9
    public function countExcludePlayers()
122
    {
123 9
        return count($this->excludePlayers);
124
    }
125
126
127
    /**
128
     * @param Player $player
129
     * @return bool
130
     * @throws PlayersCollectionException
131
     */
132 18
    private function isDuplicatePlayer(Player $player)
133
    {
134 18
        if (array_key_exists($player->id(), $this->players)) {
135 4
            throw  new PlayersCollectionException('Duplicate player: '.$player->email());
136
        }
137
138 18
        return false;
139
    }
140
141
    /**
142
     * @param Player $player
143
     * @param Player $otherPlayer
144
     * @return bool
145
     */
146 16
    private function areDifferentPlayers(Player $player, Player $otherPlayer)
147
    {
148 16
        return $player->id() != $otherPlayer->id();
149
    }
150
151
    /**
152
     * @param array $list
153
     * @return array
154
     */
155 9
    private function shuffleAssoc($list)
156
    {
157 9
        if (!is_array($list)) return $list;
158
159 9
        $keys = $this->forceShuffle(array_keys($list));
160 9
        $random = [];
161 9
        foreach ($keys as $key) {
162 9
            $random[$key] = $list[$key];
163 9
        }
164
165 9
        return $random;
166
    }
167
168
    /**
169
     * @param array $list
170
     * @return array
171
     */
172 9
    private function forceShuffle($list)
173
    {
174 9
        if (!is_array($list) || count($list) < 2) return $list;
175
176 9
        $shuffleList = $list;
177 9
        while ($shuffleList == $list) {
178 9
            shuffle($shuffleList);
179 9
        }
180
181 9
        return $shuffleList;
182
    }
183
}