This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Hangman\Entity; |
||
4 | |||
5 | use Broadway\EventSourcing\EventSourcedAggregateRoot; |
||
6 | use Hangman\Event\HangmanGameCreatedEvent; |
||
7 | use Hangman\Event\HangmanGameFailedStartingEvent; |
||
8 | use Hangman\Event\HangmanGameLostEvent; |
||
9 | use Hangman\Event\HangmanGameStartedEvent; |
||
10 | use Hangman\Event\HangmanPlayerCreatedEvent; |
||
11 | use Hangman\Event\HangmanPlayerFailedCreatingEvent; |
||
12 | use Hangman\Event\HangmanPlayerLostEvent; |
||
13 | use Hangman\Event\HangmanPlayerProposedInvalidAnswerEvent; |
||
14 | use Hangman\Event\HangmanPlayerTriedPlayingDuringAnotherPlayerTurnEvent; |
||
15 | use Hangman\Event\HangmanPlayerTriedPlayingInactiveGameEvent; |
||
16 | use Hangman\Event\HangmanPlayerTurnEvent; |
||
17 | use Hangman\Exception\HangmanException; |
||
18 | use Hangman\Exception\HangmanPlayerOptionsException; |
||
19 | use Hangman\Move\Answer; |
||
20 | use Hangman\Move\Proposition; |
||
21 | use Hangman\Options\HangmanPlayerOptions; |
||
22 | use Hangman\PlayersCollection; |
||
23 | use Hangman\Result\HangmanBadProposition; |
||
24 | use Hangman\Result\HangmanGoodProposition; |
||
25 | use Hangman\Result\HangmanLost; |
||
26 | use Hangman\Result\HangmanWon; |
||
27 | use Hangman\Word; |
||
28 | use MiniGame\Entity\MiniGame; |
||
29 | use MiniGame\Entity\MiniGameId; |
||
30 | use MiniGame\Entity\Player; |
||
31 | use MiniGame\Entity\PlayerId; |
||
32 | use MiniGame\Entity\PlayTrait; |
||
33 | use MiniGame\GameResult; |
||
34 | use MiniGame\PlayerOptions; |
||
35 | |||
36 | class Hangman extends EventSourcedAggregateRoot implements MiniGame |
||
37 | { |
||
38 | use PlayTrait; |
||
39 | |||
40 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
41 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
42 | ////////////////////////////////////////////// CONSTANTS /////////////////////////////////////////////////// |
||
43 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
44 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
45 | |||
46 | const STATE_UNINITIALIZED = 'uninitialized'; |
||
47 | const STATE_READY = 'ready'; |
||
48 | const STATE_STARTED = 'started'; |
||
49 | const STATE_OVER = 'over'; |
||
50 | |||
51 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
52 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
53 | ///////////////////////////////////////////// PROPERTIES /////////////////////////////////////////////////// |
||
54 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
55 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
56 | |||
57 | /** |
||
58 | * @var MiniGameId |
||
59 | */ |
||
60 | private $id; |
||
61 | |||
62 | /** |
||
63 | * @var Word |
||
64 | */ |
||
65 | private $word; |
||
66 | |||
67 | /** |
||
68 | * @var PlayersCollection |
||
69 | **/ |
||
70 | private $players; |
||
71 | |||
72 | /** |
||
73 | * @var string |
||
74 | */ |
||
75 | private $state; |
||
76 | |||
77 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
78 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
79 | ///////////////////////////////////////// PRIVATE CONSTRUCTOR ////////////////////////////////////////////// |
||
80 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
81 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
82 | |||
83 | /** |
||
84 | * Constructor |
||
85 | */ |
||
86 | 114 | private function __construct() |
|
87 | { |
||
88 | 114 | $this->state = self::STATE_UNINITIALIZED; |
|
89 | 114 | } |
|
90 | |||
91 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
92 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
93 | ////////////////////////////////////////////// ACCESSORS /////////////////////////////////////////////////// |
||
94 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
95 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
96 | |||
97 | /** |
||
98 | * Returns the id of the game |
||
99 | * |
||
100 | * @return MiniGameId |
||
101 | */ |
||
102 | 87 | public function getId() |
|
103 | 12 | { |
|
104 | 87 | return $this->id; |
|
105 | } |
||
106 | |||
107 | /** |
||
108 | * Returns the aggregate id |
||
109 | * |
||
110 | * @return string |
||
111 | */ |
||
112 | 114 | public function getAggregateRootId() |
|
113 | { |
||
114 | 114 | return (string) $this->id; |
|
115 | } |
||
116 | |||
117 | /** |
||
118 | * Returns the name of the mini-game |
||
119 | * |
||
120 | * @return string |
||
121 | */ |
||
122 | 3 | public static function getName() |
|
123 | { |
||
124 | 3 | return 'HANGMAN'; |
|
125 | } |
||
126 | |||
127 | /** |
||
128 | * Get the player identified by PlayerId |
||
129 | * |
||
130 | * @param PlayerId $playerId |
||
131 | * |
||
132 | * @return HangmanPlayer |
||
133 | */ |
||
134 | 12 | public function getPlayer(PlayerId $playerId = null) |
|
135 | { |
||
136 | 12 | if ($playerId === null) { |
|
137 | 3 | return null; |
|
138 | } |
||
139 | |||
140 | 9 | return $this->players->get((string)$playerId); |
|
141 | } |
||
142 | |||
143 | /** |
||
144 | * Returns the player who can play |
||
145 | * |
||
146 | * @return Player |
||
147 | */ |
||
148 | 3 | public function getCurrentPlayer() |
|
149 | { |
||
150 | 3 | return $this->players->getCurrentPlayer(); |
|
151 | } |
||
152 | |||
153 | /** |
||
154 | * Get the players |
||
155 | * |
||
156 | * @return Player[] |
||
157 | */ |
||
158 | 114 | public function getPlayers() |
|
159 | { |
||
160 | 114 | return $this->players->toArray(); |
|
161 | } |
||
162 | |||
163 | /** |
||
164 | * Is game started? |
||
165 | * |
||
166 | * @return bool |
||
167 | */ |
||
168 | 36 | public function isGameStarted() |
|
169 | { |
||
170 | 36 | return $this->state === self::STATE_STARTED; |
|
171 | } |
||
172 | |||
173 | /** |
||
174 | * Is it the player's turn? |
||
175 | * |
||
176 | * @param PlayerId $playerId |
||
177 | * |
||
178 | * @return bool |
||
179 | */ |
||
180 | 36 | public function canPlayerPlay(PlayerId $playerId) |
|
181 | { |
||
182 | 36 | return $this->players->canPlay($playerId); |
|
183 | } |
||
184 | |||
185 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
186 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
187 | /////////////////////////////////////////// DOMAIN METHODS ///////////////////////////////////////////////// |
||
188 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
189 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
190 | |||
191 | /** |
||
192 | * Starts the game |
||
193 | * |
||
194 | * @param PlayerId $playerId |
||
195 | * |
||
196 | * @return GameResult |
||
197 | */ |
||
198 | 51 | public function startGame(PlayerId $playerId) |
|
199 | { |
||
200 | 51 | if (! $this->isGameReady()) { |
|
201 | 3 | return $this->failStarting($playerId, HangmanGameFailedStartingEvent::BAD_STATE); |
|
202 | } |
||
203 | |||
204 | 51 | if (! $this->players->hasPlayers()) { |
|
205 | 3 | return $this->failStarting($playerId, HangmanGameFailedStartingEvent::NO_PLAYER); |
|
206 | } |
||
207 | |||
208 | 48 | $event = new HangmanGameStartedEvent($this->id, $playerId); |
|
209 | 48 | $this->apply($event); |
|
210 | |||
211 | 48 | $this->setNextPlayer($playerId); |
|
212 | |||
213 | 48 | return $event; |
|
214 | } |
||
215 | |||
216 | /** |
||
217 | * Adds a player to the game |
||
218 | * |
||
219 | * @param PlayerOptions $playerOptions |
||
220 | * |
||
221 | * @throws HangmanPlayerOptionsException |
||
222 | * @throws HangmanException |
||
223 | * |
||
224 | * @return GameResult |
||
225 | */ |
||
226 | 66 | public function addPlayerToGame(PlayerOptions $playerOptions) |
|
227 | { |
||
228 | 66 | if (! $playerOptions instanceof HangmanPlayerOptions) { |
|
229 | 3 | throw new HangmanPlayerOptionsException( |
|
230 | 3 | $playerOptions->getPlayerId(), |
|
231 | 3 | $this->getId(), |
|
232 | 1 | 'Options are not recognized' |
|
233 | 2 | ); |
|
234 | } |
||
235 | |||
236 | 63 | if (! $this->isGameReady()) { |
|
237 | 3 | $event = new HangmanPlayerFailedCreatingEvent( |
|
238 | 3 | $this->id, |
|
239 | 3 | $playerOptions->getPlayerId(), |
|
240 | 3 | $playerOptions->getExternalReference() |
|
241 | 2 | ); |
|
242 | 3 | $this->apply($event); |
|
243 | 3 | return $event; |
|
244 | } |
||
245 | |||
246 | 63 | $event = new HangmanPlayerCreatedEvent( |
|
247 | 63 | $this->id, |
|
248 | 63 | $playerOptions->getPlayerId(), |
|
249 | 63 | $playerOptions->getName(), |
|
250 | 63 | $playerOptions->getLives(), |
|
251 | 63 | $playerOptions->getExternalReference() |
|
252 | 42 | ); |
|
253 | 63 | $this->apply($event); |
|
254 | 63 | return $event; |
|
255 | } |
||
256 | |||
257 | /** |
||
258 | * A player leaves the game |
||
259 | * |
||
260 | * @param PlayerId $playerId |
||
261 | * |
||
262 | * @return GameResult |
||
263 | */ |
||
264 | 9 | public function leaveGame(PlayerId $playerId) |
|
265 | { |
||
266 | 9 | switch ($this->state) { |
|
267 | 9 | case self::STATE_STARTED: |
|
268 | 3 | $player = $this->getPlayer($playerId); |
|
269 | 3 | return $player ? $this->playerLoses($player) : null; |
|
270 | 6 | case self::STATE_OVER: |
|
271 | 3 | break; |
|
272 | 2 | default: |
|
273 | 3 | $this->players->remove((string) $playerId); |
|
274 | 3 | break; |
|
275 | 4 | } |
|
276 | 6 | return null; |
|
277 | 4 | } |
|
278 | |||
279 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
280 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
281 | ////////////////////////////////////////// PRIVATE METHODS ///////////////////////////////////////////////// |
||
282 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
283 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
284 | |||
285 | /** |
||
286 | * Initialize the game |
||
287 | * |
||
288 | * @param MiniGameId $id |
||
289 | * @param string $word |
||
290 | */ |
||
291 | 114 | private function initialize(MiniGameId $id, $word) |
|
292 | { |
||
293 | 114 | $this->apply(new HangmanGameCreatedEvent($id, $word)); |
|
294 | 114 | } |
|
295 | |||
296 | /** |
||
297 | * @return bool |
||
298 | */ |
||
299 | 66 | private function isGameReady() |
|
300 | { |
||
301 | 66 | return $this->state === self::STATE_READY; |
|
302 | } |
||
303 | |||
304 | /** |
||
305 | * @param PlayerId $playerId |
||
306 | * @param string $reason |
||
307 | * |
||
308 | * @return HangmanGameFailedStartingEvent |
||
309 | */ |
||
310 | 6 | private function failStarting(PlayerId $playerId, $reason) |
|
311 | { |
||
312 | 6 | $event = new HangmanGameFailedStartingEvent( |
|
313 | 6 | $this->id, |
|
314 | 4 | $playerId, |
|
315 | $reason |
||
316 | 4 | ); |
|
317 | 6 | $this->apply($event); |
|
318 | 6 | return $event; |
|
319 | } |
||
320 | |||
321 | /** |
||
322 | * Player proposes a letter |
||
323 | * |
||
324 | * @param PlayerId $playerId |
||
325 | * @param Proposition $move |
||
326 | * |
||
327 | * @return GameResult |
||
328 | */ |
||
329 | 21 | private function playProposition(PlayerId $playerId, Proposition $move) |
|
330 | { |
||
331 | 21 | if ($errorEvent = $this->ensurePlayerCanPlay($playerId)) { |
|
332 | 6 | $this->apply($errorEvent); |
|
333 | 6 | return $errorEvent; |
|
334 | } |
||
335 | |||
336 | 15 | return $this->currentPlayerProposeLetter($move->getText()); |
|
337 | } |
||
338 | |||
339 | /** |
||
340 | * Player tries an answer |
||
341 | * |
||
342 | * @param PlayerId $playerId |
||
343 | * @param Answer $move |
||
344 | * |
||
345 | * @return GameResult |
||
346 | */ |
||
347 | 15 | private function playAnswer(PlayerId $playerId, Answer $move) |
|
348 | { |
||
349 | 15 | if ($errorEvent = $this->ensurePlayerCanPlay($playerId)) { |
|
350 | 3 | $this->apply($errorEvent); |
|
351 | 3 | return $errorEvent; |
|
352 | } |
||
353 | |||
354 | try { |
||
355 | 12 | return $this->currentPlayerProposeAnswer($move->getText()); |
|
356 | 3 | } catch (HangmanException $e) { |
|
357 | 3 | $event = new HangmanPlayerProposedInvalidAnswerEvent( |
|
358 | 3 | $this->getId(), |
|
359 | 2 | $playerId, |
|
360 | $move |
||
361 | 2 | ); |
|
362 | 3 | $this->apply($event); |
|
363 | 3 | return $event; |
|
364 | } |
||
365 | } |
||
366 | |||
367 | /** |
||
368 | * Returns an error event if player cannot play |
||
369 | * |
||
370 | * @param PlayerId $playerId |
||
371 | * |
||
372 | * @return GameResult |
||
373 | */ |
||
374 | 36 | private function ensurePlayerCanPlay(PlayerId $playerId) |
|
375 | { |
||
376 | 36 | if (!$this->isGameStarted()) { |
|
377 | 3 | $event = new HangmanPlayerTriedPlayingInactiveGameEvent( |
|
378 | 3 | $this->getId(), |
|
379 | $playerId |
||
380 | 2 | ); |
|
381 | 3 | return $event; |
|
382 | } |
||
383 | |||
384 | 33 | if (!$this->canPlayerPlay($playerId)) { |
|
385 | 6 | $event = new HangmanPlayerTriedPlayingDuringAnotherPlayerTurnEvent( |
|
386 | 6 | $this->getId(), |
|
387 | $playerId |
||
388 | 4 | ); |
|
389 | 6 | return $event; |
|
390 | } |
||
391 | |||
392 | 27 | return null; |
|
393 | } |
||
394 | |||
395 | /** |
||
396 | * Propose a letter |
||
397 | * |
||
398 | * @param string $letter |
||
399 | * |
||
400 | * @return HangmanBadProposition | HangmanGoodProposition |
||
401 | */ |
||
402 | 15 | private function currentPlayerProposeLetter($letter) |
|
403 | { |
||
404 | 15 | $result = (!$this->word->contains($letter)) |
|
405 | 13 | ? $this->currentPlayerBadProposition($letter) // remove a life |
|
406 | 15 | : $this->currentPlayerGoodProposition($letter); // yay! |
|
407 | |||
408 | 15 | return $result; |
|
409 | } |
||
410 | |||
411 | /** |
||
412 | * Propose an answer |
||
413 | * |
||
414 | * @param string $answer |
||
415 | * |
||
416 | * @return HangmanLost | HangmanWon |
||
417 | */ |
||
418 | 12 | private function currentPlayerProposeAnswer($answer) |
|
419 | { |
||
420 | 12 | $this->checkAnswerIsValid($answer); |
|
421 | |||
422 | 9 | if (! $this->word->equals($answer)) { |
|
423 | 6 | return $this->playerLoses($this->players->getCurrentPlayer()); // you lose |
|
424 | } |
||
425 | |||
426 | 3 | return $this->playerWins($this->players->getCurrentPlayer()); // you win |
|
427 | } |
||
428 | |||
429 | /** |
||
430 | * Function to call when a bad proposition has been made |
||
431 | * |
||
432 | * @param string $letter |
||
433 | * |
||
434 | * @return HangmanBadProposition | HangmanLost |
||
435 | */ |
||
436 | 9 | private function currentPlayerBadProposition($letter) |
|
437 | { |
||
438 | 9 | $player = $this->players->getCurrentPlayer(); |
|
439 | |||
440 | 9 | $event = $player->playBadLetter($letter, 1); |
|
441 | |||
442 | 9 | if ($event->getRemainingLives() === 0) { |
|
443 | 6 | return $this->playerLoses($player); |
|
444 | } |
||
445 | |||
446 | 3 | $this->setNextPlayer($this->players->getNextPlayerId()); |
|
447 | |||
448 | 3 | return $event; |
|
449 | } |
||
450 | |||
451 | /** |
||
452 | * Function to call after a good proposition of letter has been made |
||
453 | * |
||
454 | * @param string $letter |
||
455 | * |
||
456 | * @return HangmanGoodProposition | HangmanWon |
||
457 | */ |
||
458 | 6 | private function currentPlayerGoodProposition($letter) |
|
459 | { |
||
460 | 6 | $player = $this->players->getCurrentPlayer(); |
|
461 | |||
462 | 6 | $event = $player->playGoodLetter($letter); |
|
463 | |||
464 | 6 | if ($this->isAllLettersFoundForPlayer($player)) { |
|
465 | 3 | return $this->playerWins($player); |
|
466 | } |
||
467 | |||
468 | 3 | $this->setNextPlayer($this->players->getNextPlayerId()); |
|
469 | |||
470 | 3 | return $event; |
|
471 | } |
||
472 | |||
473 | /** |
||
474 | * Function to call when game is won by a player |
||
475 | * |
||
476 | * @param HangmanPlayer $player |
||
477 | * |
||
478 | * @return HangmanWon |
||
479 | */ |
||
480 | 6 | private function playerWins(HangmanPlayer $player) |
|
481 | { |
||
482 | 6 | $event = $player->win($this->word); |
|
483 | |||
484 | 6 | foreach ($this->players as $otherPlayer) { |
|
485 | 6 | if ($otherPlayer->equals($player) || $otherPlayer->hasLost()) { |
|
486 | 6 | continue; |
|
487 | } |
||
488 | 6 | $otherPlayer->lose($this->word); |
|
489 | 4 | } |
|
490 | |||
491 | 6 | return $event; |
|
492 | } |
||
493 | |||
494 | /** |
||
495 | * Function to call when game is lost by a player |
||
496 | * |
||
497 | * @param HangmanPlayer $player |
||
498 | * |
||
499 | * @return hangmanLost | HangmanGameLostEvent |
||
500 | */ |
||
501 | 15 | private function playerLoses(HangmanPlayer $player) |
|
502 | { |
||
503 | 15 | $event = $player->lose($this->word); |
|
504 | |||
505 | 15 | if ($this->players->hasAtLeastOneActivePlayer() && |
|
506 | 13 | $this->players->isCurrentPlayer($player->getId()) |
|
507 | 10 | ) { |
|
508 | 12 | $this->setNextPlayer($this->players->getNextPlayerId()); |
|
509 | 12 | return $event; |
|
510 | } |
||
511 | |||
512 | 3 | $event = new HangmanGameLostEvent( |
|
513 | 3 | $this->id, |
|
514 | 3 | $player->getId(), |
|
515 | 3 | (string) $this->word |
|
516 | 2 | ); |
|
517 | 3 | $this->apply($event); |
|
518 | |||
519 | 3 | return $event; |
|
520 | } |
||
521 | |||
522 | /** |
||
523 | * Sets the next player |
||
524 | * |
||
525 | * @param PlayerId $id |
||
526 | */ |
||
527 | 48 | private function setNextPlayer(PlayerId $id = null) |
|
528 | { |
||
529 | 48 | if ($id === null || $this->players->isCurrentPlayer($id)) { |
|
530 | 48 | return; |
|
531 | } |
||
532 | |||
533 | 18 | $this->apply( |
|
534 | 18 | new HangmanPlayerTurnEvent($this->getId(), $id) |
|
535 | 12 | ); |
|
536 | 18 | } |
|
537 | |||
538 | /** |
||
539 | * Build the word from played letters |
||
540 | * |
||
541 | * @param string[] $playedLetters |
||
542 | * |
||
543 | * @return string |
||
544 | */ |
||
545 | 42 | public function buildWord($playedLetters) |
|
546 | { |
||
547 | 42 | return $this->word->buildWord($playedLetters); |
|
548 | } |
||
549 | |||
550 | /** |
||
551 | * Checks if all letters for the word have been found |
||
552 | * |
||
553 | * @param HangmanPlayer $player |
||
554 | * |
||
555 | * @return bool |
||
556 | */ |
||
557 | 6 | private function isAllLettersFoundForPlayer(HangmanPlayer $player) |
|
558 | { |
||
559 | 6 | $wordLetters = $this->word->getLetters(); |
|
560 | 6 | $playerLetters = $player->getPlayedLetters(); |
|
561 | 6 | return count(array_intersect($wordLetters, $playerLetters)) == count($wordLetters); |
|
562 | } |
||
563 | |||
564 | /** |
||
565 | * Checks if the answer is valid |
||
566 | * If it's not, ends player turn and throws an HangmanException |
||
567 | * |
||
568 | * @param string $answer |
||
569 | * |
||
570 | * @throws HangmanException |
||
571 | */ |
||
572 | 12 | private function checkAnswerIsValid($answer) |
|
573 | { |
||
574 | 12 | if (! $this->word->isValid($answer)) { |
|
575 | 3 | throw new HangmanException(sprintf('"%s" is not a valid answer!', $answer)); |
|
576 | } |
||
577 | 9 | } |
|
578 | |||
579 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
580 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
581 | //////////////////////////////////////////// APPLY EVENTS ////////////////////////////////////////////////// |
||
582 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
583 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
584 | |||
585 | /** |
||
586 | * Apply the game created event |
||
587 | * |
||
588 | * @param HangmanGameCreatedEvent $event |
||
589 | * |
||
590 | * @return void |
||
591 | */ |
||
592 | 114 | protected function applyHangmanGameCreatedEvent(HangmanGameCreatedEvent $event) |
|
593 | { |
||
594 | 114 | $this->id = $event->getGameId(); |
|
595 | 114 | $this->word = new Word($event->getWord()); |
|
596 | 114 | $this->players = new PlayersCollection(); |
|
597 | 114 | $this->state = self::STATE_READY; |
|
598 | 114 | } |
|
599 | |||
600 | /** |
||
601 | * Apply the player created event |
||
602 | * |
||
603 | * @param HangmanPlayerCreatedEvent $event |
||
604 | * |
||
605 | * @return void |
||
606 | */ |
||
607 | 63 | protected function applyHangmanPlayerCreatedEvent(HangmanPlayerCreatedEvent $event) |
|
608 | { |
||
609 | 63 | $this->players->add( |
|
610 | 63 | new HangmanPlayer( |
|
611 | 63 | $event->getPlayerId(), |
|
612 | 63 | $event->getPlayerName(), |
|
613 | 63 | $event->getLives(), |
|
614 | 42 | $this, |
|
615 | 63 | $event->getExternalReference() |
|
616 | 42 | ) |
|
617 | 42 | ); |
|
618 | 63 | } |
|
619 | |||
620 | /** |
||
621 | * Apply the game created event |
||
622 | */ |
||
623 | 48 | protected function applyHangmanGameStartedEvent() |
|
624 | { |
||
625 | 48 | $this->state = self::STATE_STARTED; |
|
626 | 48 | } |
|
627 | |||
628 | /** |
||
629 | * Apply the player turn event |
||
630 | * |
||
631 | * @param HangmanPlayerTurnEvent $event |
||
632 | */ |
||
633 | 18 | protected function applyHangmanPlayerTurnEvent(HangmanPlayerTurnEvent $event) |
|
634 | { |
||
635 | 18 | $this->players->setCurrentPlayer($event->getPlayerId()); |
|
636 | 18 | } |
|
637 | |||
638 | /** |
||
639 | * Apply the hangman player lost event |
||
640 | * |
||
641 | * @param HangmanPlayerLostEvent $event |
||
642 | */ |
||
643 | 21 | protected function applyHangmanPlayerLostEvent(HangmanPlayerLostEvent $event) |
|
0 ignored issues
–
show
|
|||
644 | { |
||
645 | 21 | $this->state = self::STATE_OVER; |
|
646 | 21 | } |
|
647 | |||
648 | /** |
||
649 | * Apply the hangman player win event |
||
650 | * |
||
651 | * @return void |
||
652 | */ |
||
653 | 6 | protected function applyHangmanPlayerWinEvent() |
|
654 | { |
||
655 | 6 | $this->players->setCurrentPlayer(null); |
|
656 | 6 | $this->state = self::STATE_OVER; |
|
657 | 6 | } |
|
658 | |||
659 | /** |
||
660 | * Apply the hangman lost by all event |
||
661 | * |
||
662 | * @return void |
||
663 | */ |
||
664 | 3 | protected function applyHangmanGameLostEvent() |
|
665 | { |
||
666 | 3 | $this->players->setCurrentPlayer(null); |
|
667 | 3 | $this->state = self::STATE_OVER; |
|
668 | 3 | } |
|
669 | |||
670 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
671 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
672 | //////////////////////////////////////////// EVENT SOURCED ///////////////////////////////////////////////// |
||
673 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
674 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
675 | |||
676 | /** |
||
677 | * @return Player[] |
||
678 | */ |
||
679 | 114 | protected function getChildEntities() |
|
680 | { |
||
681 | 114 | return $this->getPlayers(); |
|
0 ignored issues
–
show
The return type of
return $this->getPlayers(); (MiniGame\Entity\Player[] ) is incompatible with the return type of the parent method Broadway\EventSourcing\E...eRoot::getChildEntities of type Broadway\EventSourcing\EventSourcedEntity[] .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
682 | } |
||
683 | |||
684 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
685 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
686 | ///////////////////////////////////////// STATIC CONSTRUCTOR /////////////////////////////////////////////// |
||
687 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
688 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
689 | |||
690 | /** |
||
691 | * Create a new instance |
||
692 | * |
||
693 | * @param MiniGameId $id |
||
694 | * @param string $word |
||
695 | * |
||
696 | * @return Hangman |
||
697 | */ |
||
698 | 114 | public static function createGame(MiniGameId $id, $word) |
|
699 | { |
||
700 | 114 | $hangman = new self(); |
|
701 | 114 | $hangman->initialize($id, $word); |
|
702 | |||
703 | 114 | return $hangman; |
|
704 | } |
||
705 | |||
706 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
707 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
708 | /////////////////////////////////////////// RECONSTITUTION ///////////////////////////////////////////////// |
||
709 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
710 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
711 | |||
712 | /** |
||
713 | * Static construction method for reconstitution |
||
714 | * |
||
715 | * @return Hangman |
||
716 | */ |
||
717 | 3 | public static function instantiateForReconstitution() |
|
718 | { |
||
719 | 3 | return new self(); |
|
720 | } |
||
721 | |||
722 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
723 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
724 | ///////////////////////////////////////// APPLY RESTRICTIONS /////////////////////////////////////////////// |
||
725 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
726 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
727 | |||
728 | /** |
||
729 | * @param mixed $event |
||
730 | * |
||
731 | * @throws HangmanException |
||
732 | */ |
||
733 | 114 | public function apply($event) |
|
734 | { |
||
735 | 114 | if (! $this->isSupportedEvent($event)) { |
|
736 | 3 | throw new HangmanException('You cannot apply a non hangman event.'); |
|
737 | } |
||
738 | |||
739 | 114 | parent::apply($event); |
|
740 | 114 | } |
|
741 | |||
742 | /** |
||
743 | * @param mixed $event |
||
744 | * |
||
745 | * @return bool |
||
746 | */ |
||
747 | 114 | private function isSupportedEvent($event) |
|
748 | { |
||
749 | return ( |
||
750 | 114 | $event instanceof GameResult && |
|
751 | 114 | ($this->id === null || $this->id == $event->getGameId()) |
|
752 | 76 | ); |
|
753 | } |
||
754 | } |
||
755 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.