Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Refactoring the Domain, Guided by Tests v3

pelshoff
October 27, 2018

Refactoring the Domain, Guided by Tests v3

pelshoff

October 27, 2018
Tweet

More Decks by pelshoff

Other Decks in Programming

Transcript

  1. 1. final class TicketService { 2. /** @var TicketRepository */

    3. private $ticketRepository; 4. 5. public function getAvailableTickets(Meeting $meeting, bool $publicOnly, User $user, 6. bool $forReserve): array { 7. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 8. 9. $availableTickets = []; 10. if ($forReserve) { 11. foreach ($tickets as $ticket) { 12. if (!$publicOnly || ($this->checkAvailability($ticket, []) 13. && $this->ticketRepository->checkAllowed($ticket, $user))) { 14. $availableTickets[$ticket->getId()] = $ticket; 15. } 16. } 17. return $availableTickets; 18. } 19. 20. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 21. 22. foreach ($tickets as $ticket) { 23. if (!$publicOnly || ($this->checkAvailability($ticket, $currentSoldPerTicket) 24. && $this->ticketRepository->checkAllowed($ticket, $user))) { 25. $availableTickets[$ticket->getId()] = $ticket; 26. } 27. } 28. 29. return $availableTickets; 30. }
  2. 1. final class TicketService { 2. /** @var TicketRepository */

    3. private $ticketRepository; 4. 5. public function getAvailableTickets(Meeting $meeting, bool $publicOnly, User $user, 6. bool $forReserve): array { 7. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 8. 9. $availableTickets = []; 10. if ($forReserve) { 11. foreach ($tickets as $ticket) { 12. if (!$publicOnly || ($this->checkAvailability($ticket, []) 13. && $this->ticketRepository->checkAllowed($ticket, $user))) { 14. $availableTickets[$ticket->getId()] = $ticket; 15. } 16. } 17. return $availableTickets; 18. } 19. 20. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 21. 22. foreach ($tickets as $ticket) { 23. if (!$publicOnly || ($this->checkAvailability($ticket, $currentSoldPerTicket) 24. && $this->ticketRepository->checkAllowed($ticket, $user))) { 25. $availableTickets[$ticket->getId()] = $ticket; 26. } 27. } 28. 29. return $availableTickets; 30. }
  3. 1. private function checkAvailability(Ticket $ticket, array $currentSoldPerTicket): bool { 2.

    if (!$ticket->getIsPublic()) { 3. return false; 4. } 5. 6. if ($ticket->getNumberOfTickets() && isset($currentSoldPerTicket[$ticket->getId()]) 7. && $currentSoldPerTicket[$ticket->getId()] >= $ticket->getNumberOfTickets()) { 8. return false; 9. } 10. 11. if ($ticket->getStartDate() && new DateTimeImmutable() < $ticket->getStartDate()) { 12. return false; 13. } 14. 15. if ($ticket->getEndDate() && new DateTimeImmutable() > $ticket->getEndDate()) { 16. return false; 17. } 18. 19. return true; 20. }
  4. 1. final class Ticket { 2. private $id; 3. private

    $isPublic; 4. private $numberOfTickets; 5. private $startDate; 6. private $endDate; 7. 8. public function __construct(int $id, bool $isPublic, int $numberOfTickets, 9. ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate) { 10. $this->id = $id; 11. $this->isPublic = $isPublic; 12. $this->numberOfTickets = $numberOfTickets; 13. $this->startDate = $startDate; 14. $this->endDate = $endDate; 15. }
  5. 1. interface TicketRepository 2. { 3. /** 4. * @param

    Meeting $meeting 5. * @return Ticket[] 6. * Do a query 7. */ 8. public function getMeetingTickets(Meeting $meeting): array; 9. /** 10. * @param Meeting $meeting 11. * @return array 12. * Do a query 13. */ 14. public function getNumberOfCurrentSoldTickets(Meeting $meeting): array; 15. /** 16. * @param Ticket $ticket 17. * @param User $user 18. * @return bool 19. * allowed by user invitation? 20. * allowed by group? 21. * allowed by selection? 22. * Anyway, do a query 23. */ 24. public function checkAllowed(Ticket $ticket, User $user): bool; 25. }
  6. 1. final class TicketServiceTest extends TestCase { 2. public function

    testThatGetAvailableTicketsGivesTheOnlyTicketAvailable() { 3. $meeting = $this->givenAnUpcomingMeeting(); 4. $ticket = $this->givenAPublicTicket(); 5. $user = $this->givenAUser(); 6. $this->whenTicketsForMeeting([$ticket], $meeting); 7. $this->whenNoTicketsSold(); 8. 9. $expected = [$ticket->getId() => $ticket]; 10. $actual = $this->ticketService->getAvailableTickets($meeting, false, $user, 11. false); 12. 13. $this->assertEquals($expected, $actual); 14. } ........... 11 / 11 (100%) Time: 32 ms, Memory: 4.00MB OK (11 tests, 11 assertions)
  7. 1. private function givenAnUpcomingMeeting() { 2. return new Meeting(...); 3.

    } 4. private function givenAPublicTicket() { 5. return new Ticket(mt_rand(), true, 0, null, null); 6. } 7. private function whenTicketsForMeeting(array $tickets, Meeting $meeting) { 8. $this->ticketRepository->expects($this->any()) 9. ->method('getMeetingTickets') 10. ->with($meeting) 11. ->will($this->returnValue($tickets)); 12. } 13. private function whenNoTicketsSold() { 14. $this->ticketRepository->expects($this->any()) 15. ->method('getNumberOfCurrentSoldTickets') 16. ->will($this->returnValue([])); 17. } 18. private function givenAUser() { 19. return new User(); 20. } 21. protected function setUp() { 22. $this->ticketRepository = $this->getMockBuilder(TicketRepository::class) 23. ->getMock(); 24. $this->ticketService = new TicketService($this->ticketRepository); 25. }
  8. 1. public function testThatGetAvailableTicketsFiltersDisallowedTickets() { 2. $meeting = $this->givenAnUpcomingMeeting(); 3.

    $allTickets = [ 4. $this->givenAPublicTicket(), 5. $this->givenAPublicTicket(), 6. $this->givenAPublicTicket(), 7. $allowedTicket = $this->givenAPublicTicket(), 8. ]; 9. $user = $this->givenAUser(); 10. $this->whenTicketsForMeeting($allTickets, $meeting); 11. $this->whenUserOnlyAllowedForTicket($allowedTicket, $user); 12. $this->whenNoTicketsSold(); 13. 14. $expected = [$allowedTicket->getId() => $allowedTicket]; 15. $actual = $this->ticketService->getAvailableTickets($meeting, true, $user, false); 16. 17. $this->assertEquals($expected, $actual); 18. } ............ 12 / 12 (100%) Time: 33 ms, Memory: 4.00MB OK (12 tests, 12 assertions)
  9. 1. private function whenUserOnlyAllowedForTicket(Ticket $ticket, User $user) { 2. $this->ticketRepository->expects($this->any())

    3. ->method('checkAllowed') 4. ->withConsecutive($this->anything(), $this->anything(), $this->anything(), 5. [$ticket, $user]) 6. ->willReturnOnConsecutiveCalls(false, false, false, true); 7. }
  10. 1. public function testThatSoldOutTicketsAreNotAvailable() { 2. $meeting = $this->givenAnUpcomingMeeting(); 3.

    $ticket = $this->givenALimitedTicket(); 4. $user = $this->givenAUser(); 5. $this->whenTicketsForMeeting([$ticket], $meeting); 6. $this->whenTicketsAreAllowed(); 7. $this->whenTicketIsSoldOut($ticket); 8. 9. $expected = []; 10. $actual = $this->ticketService->getAvailableTickets($meeting, true, $user, false); 11. 12. $this->assertEquals($expected, $actual); 13. } 14. public function testThatSoldOutTicketsAreAvailableForReserve() { 15. $meeting = $this->givenAnUpcomingMeeting(); 16. $ticket = $this->givenALimitedTicket(); 17. $user = $this->givenAUser(); 18. $this->whenTicketsForMeeting([$ticket], $meeting); 19. $this->whenTicketsAreAllowed(); 20. $this->whenTicketIsSoldOut($ticket); 21. 22. $expected = [$ticket->getId() => $ticket]; 23. $actual = $this->ticketService->getAvailableTickets($meeting, true, $user, true); 24. 25. $this->assertEquals($expected, $actual); 26. } OK (14 tests, 14 assertions)
  11. 1. public function getAvailableTickets(Meeting $meeting, bool $publicOnly, User $user, 2.

    bool $forReserve): array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. 5. $availableTickets = []; 6. if ($forReserve) { 7. foreach ($tickets as $ticket) { 8. if (!$publicOnly || ($this->checkAvailability($ticket, []) 9. && $this->ticketRepository->checkAllowed($ticket, $user))) { 10. $availableTickets[$ticket->getId()] = $ticket; 11. } 12. } 13. return $availableTickets; 14. } 15. 16. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 17. 18. foreach ($tickets as $ticket) { 19. if (!$publicOnly || ($this->checkAvailability($ticket, $currentSoldPerTicket) 20. && $this->ticketRepository->checkAllowed($ticket, $user))) { 21. $availableTickets[$ticket->getId()] = $ticket; 22. } 23. } 24. 25. return $availableTickets; 26. }
  12. 1. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 2. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 3. $ticketIsAvailableForReserve

    = $ticketIsAvailableOtherwise = $ticketIsAllowedForUser = []; 4. foreach ($tickets as $ticket) { 5. $ticketIsAvailableForReserve[$ticket->getId()] = $this->checkAvailability($ticket, []); 6. $ticketIsAvailableOtherwise[$ticket->getId()] = 7. $this->checkAvailability($ticket, $currentSoldPerTicket); 8. $ticketIsAllowedForUser[$ticket->getId()] = 9. $this->ticketRepository->checkAllowed($ticket, $user); 10. } 11. 12. $availableTickets = []; 13. if ($forReserve) { 14. foreach ($tickets as $ticket) { 15. if (!$publicOnly || ($ticketIsAvailableForReserve[$ticket->getId()] 16. && $ticketIsAllowedForUser[$ticket->getId()])) { 17. $availableTickets[$ticket->getId()] = $ticket; 18. } 19. } 20. return $availableTickets; 21. } 22. 23. foreach ($tickets as $ticket) { 24. if (!$publicOnly || ($ticketIsAvailableOtherwise[$ticket->getId()] 25. && $ticketIsAllowedForUser[$ticket->getId()])) { 26. $availableTickets[$ticket->getId()] = $ticket; 27. } 28. } 29. 30. return $availableTickets;
  13. 1. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 2. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 3. $ticketIsAvailableForReserve

    = $ticketIsAvailableOtherwise = $ticketIsAllowedForUser = []; 4. foreach ($tickets as $ticket) { 5. $ticketIsAvailableForReserve[$ticket->getId()] = $this->checkAvailability($ticket, []); 6. $ticketIsAvailableOtherwise[$ticket->getId()] = 7. $this->checkAvailability($ticket, $currentSoldPerTicket); 8. $ticketIsAllowedForUser[$ticket->getId()] = 9. $this->ticketRepository->checkAllowed($ticket, $user); 10. } 11. 12. $availableTickets = []; 13. if ($forReserve) { 14. foreach ($tickets as $ticket) { 15. if (!$publicOnly || ($ticketIsAvailableForReserve[$ticket->getId()] 16. && $ticketIsAllowedForUser[$ticket->getId()])) { 17. $availableTickets[$ticket->getId()] = $ticket; 18. } 19. } 20. return $availableTickets; 21. } 22. 23. foreach ($tickets as $ticket) { 24. if (!$publicOnly || ($ticketIsAvailableOtherwise[$ticket->getId()] 25. && $ticketIsAllowedForUser[$ticket->getId()])) { 26. $availableTickets[$ticket->getId()] = $ticket; 27. } 28. } 29. 30. return $availableTickets;
  14. 1. public function getAvailableTickets(Meeting $meeting, bool $publicOnly, User $user, 2.

    bool $forReserve): array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 5. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = $ticketIsAllowedForUser = []; 6. foreach ($tickets as $ticket) { 7. $ticketIsAvailableForReserve[$ticket->getId()] = $this->checkAvailability($ticket, []); 8. $ticketIsAvailableOtherwise[$ticket->getId()] = 9. $this->checkAvailability($ticket, $currentSoldPerTicket); 10. $ticketIsAllowedForUser[$ticket->getId()] = 11. $this->ticketRepository->checkAllowed($ticket, $user); 12. } 13. 14. $ticketIsAvailable = $forReserve ? $ticketIsAvailableForReserve : $ticketIsAvailableOtherwise; 15. 16. $availableTickets = []; 17. foreach ($tickets as $ticket) { 18. if (!$publicOnly || ($ticketIsAvailable[$ticket->getId()] 19. && $ticketIsAllowedForUser[$ticket->getId()])) { 20. $availableTickets[$ticket->getId()] = $ticket; 21. } 22. } 23. 24. return $availableTickets; 25. } OK (14 tests, 14 assertions)
  15. 1. public function getAvailableTickets(Meeting $meeting, bool $publicOnly, User $user, 2.

    bool $forReserve): array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 5. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = $ticketIsAllowedForUser = []; 6. foreach ($tickets as $ticket) { 7. $ticketIsAvailableForReserve[$ticket->getId()] = $this->checkAvailability($ticket, []); 8. $ticketIsAvailableOtherwise[$ticket->getId()] = 9. $this->checkAvailability($ticket, $currentSoldPerTicket); 10. $ticketIsAllowedForUser[$ticket->getId()] = 11. $this->ticketRepository->checkAllowed($ticket, $user); 12. } 13. 14. $ticketIsAvailable = $forReserve ? $ticketIsAvailableForReserve : $ticketIsAvailableOtherwise; 15. 16. $availableTickets = []; 17. foreach ($tickets as $ticket) { 18. if (!$publicOnly || ($ticketIsAvailable[$ticket->getId()] 19. && $ticketIsAllowedForUser[$ticket->getId()])) { 20. $availableTickets[$ticket->getId()] = $ticket; 21. } 22. } 23. 24. return $availableTickets; 25. }
  16. 1. private function checkAvailability(Ticket $ticket, array $currentSoldPerTicket): bool { 2.

    if (!$ticket->getIsPublic()) { 3. return false; 4. } 5. 6. if ($ticket->getNumberOfTickets() && isset($currentSoldPerTicket[$ticket->getId()]) 7. && $currentSoldPerTicket[$ticket->getId()] >= $ticket->getNumberOfTickets()) { 8. return false; 9. } 10. 11. if ($ticket->getStartDate() && new DateTimeImmutable() < $ticket->getStartDate()) { 12. return false; 13. } 14. 15. if ($ticket->getEndDate() && new DateTimeImmutable() > $ticket->getEndDate()) { 16. return false; 17. } 18. 19. return true; 20. }
  17. 1. private function checkAvailability(Ticket $ticket, array $currentSoldPerTicket): bool { 2.

    return $this->ticketIsOpenForSale($ticket) 3. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 4. } 5. private function thereAreTicketsLeftForSale(Ticket $ticket, array $currentSoldPerTicket): 6. bool { 7. if ($ticket->getNumberOfTickets() && isset($currentSoldPerTicket[$ticket->getId()]) 8. && $currentSoldPerTicket[$ticket->getId()] >= $ticket->getNumberOfTickets()) { 9. return false; 10. } 11. return true; 12. } 13. private function ticketIsOpenForSale(Ticket $ticket): bool { 14. if (!$ticket->isPublic()) { 15. return false; 16. } 17. if ($ticket->getStartDate() && new DateTimeImmutable() < $ticket->getStartDate()) { 18. return false; 19. } 20. if ($ticket->getEndDate() && new DateTimeImmutable() > $ticket->getEndDate()) { 21. return false; 22. } 23. return true; 24. }
  18. 1. private function checkAvailability(Ticket $ticket, array $currentSoldPerTicket): bool { 2.

    return $this->ticketIsOpenForSale($ticket) 3. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 4. } 5. private function thereAreTicketsLeftForSale(Ticket $ticket, array $currentSoldPerTicket): 6. bool { 7. if ($ticket->getNumberOfTickets() && isset($currentSoldPerTicket[$ticket->getId()]) 8. && $currentSoldPerTicket[$ticket->getId()] >= $ticket->getNumberOfTickets()) { 9. return false; 10. } 11. return true; 12. } 13. private function ticketIsOpenForSale(Ticket $ticket): bool { 14. if (!$ticket->isPublic()) { 15. return false; 16. } 17. if ($ticket->getStartDate() && new DateTimeImmutable() < $ticket->getStartDate()) { 18. return false; 19. } 20. if ($ticket->getEndDate() && new DateTimeImmutable() > $ticket->getEndDate()) { 21. return false; 22. } 23. return true; 24. }
  19. 1. private function checkAvailability(Ticket $ticket, array $currentSoldPerTicket): bool { 2.

    return $ticket->isOpenForSaleOn(new DateTimeImmutable()) 3. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 4. } 5. private function thereAreTicketsLeftForSale(Ticket $ticket, array $currentSoldPerTicket): 6. bool { 7. if ($ticket->getNumberOfTickets() && isset($currentSoldPerTicket[$ticket->getId()]) 8. && $currentSoldPerTicket[$ticket->getId()] >= $ticket->getNumberOfTickets()) { 9. return false; 10. } 11. return true; 12. } 13. final class Ticket { 14. public function isOpenForSaleOn(DateTimeImmutable $date): bool { 15. if (!$this->isPublic()) { 16. return false; 17. } 18. if ($this->getStartDate() && $date < $this->getStartDate()) { 19. return false; 20. } 21. if ($this->getEndDate() && $date > $this->getEndDate()) { 22. return false; 23. } 24. return true; 25. }
  20. 1. private function checkAvailability(Ticket $ticket, array $currentSoldPerTicket): bool { 2.

    return $ticket->isOpenForSaleOn(new DateTimeImmutable()) 3. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 4. } 5. private function thereAreTicketsLeftForSale(Ticket $ticket, array $currentSoldPerTicket): 6. bool { 7. if ($ticket->getNumberOfTickets() && isset($currentSoldPerTicket[$ticket->getId()]) 8. && $currentSoldPerTicket[$ticket->getId()] >= $ticket->getNumberOfTickets()) { 9. return false; 10. } 11. return true; 12. } 13. final class Ticket { 14. public function isOpenForSaleOn(DateTimeImmutable $date): bool { 15. if (!$this->isPublic()) { 16. return false; 17. } 18. if ($this->getStartDate() && $date < $this->getStartDate()) { 19. return false; 20. } 21. if ($this->getEndDate() && $date > $this->getEndDate()) { 22. return false; 23. } 24. return true; 25. }
  21. 1. public function getAvailableTickets(Meeting $meeting, bool $publicOnly, User $user, 2.

    bool $forReserve): array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 5. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = $ticketIsAllowedForUser = []; 6. foreach ($tickets as $ticket) { 7. $ticketIsAvailableForReserve[$ticket->getId()] = $this->checkAvailability($ticket, []); 8. $ticketIsAvailableOtherwise[$ticket->getId()] = 9. $this->checkAvailability($ticket, $currentSoldPerTicket); 10. $ticketIsAllowedForUser[$ticket->getId()] = 11. $this->ticketRepository->checkAllowed($ticket, $user); 12. } 13. 14. $ticketIsAvailable = $forReserve ? $ticketIsAvailableForReserve : $ticketIsAvailableOtherwise; 15. 16. $availableTickets = []; 17. foreach ($tickets as $ticket) { 18. if (!$publicOnly || ($ticketIsAvailable[$ticket->getId()] 19. && $ticketIsAllowedForUser[$ticket->getId()])) { 20. $availableTickets[$ticket->getId()] = $ticket; 21. } 22. } 23. 24. return $availableTickets; 25. }
  22. 1. public function getAvailableTickets(Meeting $meeting, bool $publicOnly, User $user, 2.

    bool $forReserve): array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 5. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = $ticketIsAllowedForUser = []; 6. $today = new DateTimeImmutable(); 7. foreach ($tickets as $ticket) { 8. $ticketIsAvailableForReserve[$ticket->getId()] = $ticket->isOpenForSaleOn($today) 9. && $this->thereAreTicketsLeftForSale($ticket, []); 10. $ticketIsAvailableOtherwise[$ticket->getId()] = $ticket->isOpenForSaleOn($today) 11. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 12. $ticketIsAllowedForUser[$ticket->getId()] = 13. $this->ticketRepository->checkAllowed($ticket, $user); 14. } 15. 16. $ticketIsAvailable = $forReserve ? $ticketIsAvailableForReserve : $ticketIsAvailableOtherwise; 17. 18. $availableTickets = []; 19. foreach ($tickets as $ticket) { 20. if (!$publicOnly || ($ticketIsAvailable[$ticket->getId()] 21. && $ticketIsAllowedForUser[$ticket->getId()])) { 22. $availableTickets[$ticket->getId()] = $ticket; 23. } 24. } 25. 26. return $availableTickets; 27. }
  23. 1. public function getAvailableTickets(Meeting $meeting, bool $publicOnly, User $user, 2.

    bool $forReserve): array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 5. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = $ticketIsAllowedForUser = []; 6. $today = new DateTimeImmutable(); 7. foreach ($tickets as $ticket) { 8. $ticketIsAvailableForReserve[$ticket->getId()] = $ticket->isOpenForSaleOn($today); 9. $ticketIsAvailableOtherwise[$ticket->getId()] = $ticket->isOpenForSaleOn($today) 10. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 11. $ticketIsAllowedForUser[$ticket->getId()] = 12. $this->ticketRepository->checkAllowed($ticket, $user); 13. } 14. 15. $ticketIsAvailable = $forReserve ? $ticketIsAvailableForReserve : $ticketIsAvailableOtherwise; 16. 17. $availableTickets = []; 18. foreach ($tickets as $ticket) { 19. if (!$publicOnly || ($ticketIsAvailable[$ticket->getId()] 20. && $ticketIsAllowedForUser[$ticket->getId()])) { 21. $availableTickets[$ticket->getId()] = $ticket; 22. } 23. } 24. 25. return $availableTickets; 26. } OK (14 tests, 14 assertions)
  24. 1. public function getAvailableTickets(Meeting $meeting, bool $publicOnly, User $user, 2.

    bool $forReserve): array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 5. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = $ticketIsAllowedForUser = []; 6. $today = new DateTimeImmutable(); 7. foreach ($tickets as $ticket) { 8. $ticketIsAvailableForReserve[$ticket->getId()] = $ticket->isOpenForSaleOn($today); 9. $ticketIsAvailableOtherwise[$ticket->getId()] = $ticket->isOpenForSaleOn($today) 10. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 11. $ticketIsAllowedForUser[$ticket->getId()] = 12. $this->ticketRepository->checkAllowed($ticket, $user); 13. } 14. 15. $ticketIsAvailable = $forReserve ? $ticketIsAvailableForReserve : $ticketIsAvailableOtherwise; 16. 17. $availableTickets = []; 18. foreach ($tickets as $ticket) { 19. if (!$publicOnly || ($ticketIsAvailable[$ticket->getId()] 20. && $ticketIsAllowedForUser[$ticket->getId()])) { 21. $availableTickets[$ticket->getId()] = $ticket; 22. } 23. } 24. 25. return $availableTickets; 26. }
  25. 1. public function getAvailableTickets(Meeting $meeting, bool $publicOnly, User $user, 2.

    bool $forReserve): array { 3. if (!$publicOnly) { 4. return $this->ticketRepository->getMeetingTickets($meeting); 5. } 6. // ... 7. 8. Failed asserting that two arrays are equal. 9. --- Expected 10. +++ Actual 11. @@ @@ 12. Array ( 13. - 1623135705 => Pelshoff\Meeting\Ticket Object (...) 14. + 0 => Pelshoff\Meeting\Ticket Object (...) 15. ) 16. 17. /data/presentatie/tests/TicketServiceTest.php:77 18. 19. FAILURES! 20. Tests: 14, Assertions: 14, Failures: 3.
  26. 1. public function getAvailableTickets(Meeting $meeting, bool $publicOnly, User $user, 2.

    bool $forReserve): array { 3. if ($publicOnly) { 4. return $this->getPubliclyAvailableTickets($meeting, $user, $forReserve); 5. } 6. return $this->getPrivatelyAvailableTickets($meeting); 7. } 8. 9. public function getPrivatelyAvailableTickets(Meeting $meeting): array { 10. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 11. foreach ($tickets as $ticket) { 12. $availableTickets[$ticket->getId()] = $ticket; 13. } 14. return $availableTickets; 15. } 16. 17. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, 18. bool $forReserve): array { 19. /**/ 20. } OK (14 tests, 14 assertions)
  27. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve):array {

    2. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 3. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 4. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = $ticketIsAllowedForUser = []; 5. $today = new DateTimeImmutable(); 6. foreach ($tickets as $ticket) { 7. $ticketIsAvailableForReserve[$ticket->getId()] = $ticket->isOpenForSaleOn($today); 8. $ticketIsAvailableOtherwise[$ticket->getId()] = $ticket->isOpenForSaleOn($today) 9. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 10. $ticketIsAllowedForUser[$ticket->getId()] = 11. $this->ticketRepository->checkAllowed($ticket, $user); 12. } 13. 14. 15. $ticketIsAvailable = $forReserve ? $ticketIsAvailableForReserve : $ticketIsAvailableOtherwise; 16. 17. $availableTickets = []; 18. foreach ($tickets as $ticket) { 19. if ($ticketIsAvailable[$ticket->getId()] && $ticketIsAllowedForUser[$ticket->getId()]) { 20. $availableTickets[$ticket->getId()] = $ticket; 21. } 22. } 23. 24. return $availableTickets; 25. }
  28. 1. final class TicketService { 2. 3. /** @deprecated Use

    getPrivatelyAvailableTickets or getPubliclyAvailableTickets */ 4. public function getAvailableTickets(Meeting $meeting, bool $publicOnly, User $user, 5. bool $forReserve): array {...} 6. 7. public function getPrivatelyAvailableTickets(Meeting $meeting): array {...} 8. 9. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, 10. bool $forReserve): array {...} 11. 12. ... 13. }
  29. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): 2.

    array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 5. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = $ticketIsAllowedForUser = []; 6. $today = new DateTimeImmutable(); 7. foreach ($tickets as $ticket) { 8. $ticketIsAvailableForReserve[$ticket->getId()] = $ticket->isOpenForSaleOn($today); 9. $ticketIsAvailableOtherwise[$ticket->getId()] = $ticket->isOpenForSaleOn($today) 10. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 11. $ticketIsAllowedForUser[$ticket->getId()] = 12. $this->ticketRepository->checkAllowed($ticket, $user); 13. } 14. 15. $ticketIsAvailable = $forReserve ? $ticketIsAvailableForReserve : $ticketIsAvailableOtherwise; 16. 17. $availableTickets = []; 18. foreach ($tickets as $ticket) { 19. if ($ticketIsAvailable[$ticket->getId()] && $ticketIsAllowedForUser[$ticket->getId()]) { 20. $availableTickets[$ticket->getId()] = $ticket; 21. } 22. } 23. 24. return $availableTickets; 25. }
  30. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): 2.

    array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 5. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = $ticketIsAllowedForUser = []; 6. $today = new DateTimeImmutable(); 7. foreach ($tickets as $ticket) { 8. $ticketIsAvailableForReserve[$ticket->getId()] = $ticket->isOpenForSaleOn($today); 9. $ticketIsAvailableOtherwise[$ticket->getId()] = $ticket->isOpenForSaleOn($today) 10. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 11. $ticketIsAllowedForUser[$ticket->getId()] = 12. $this->ticketRepository->checkAllowed($ticket, $user); 13. } 14. 15. $ticketIsAvailable = $forReserve ? $ticketIsAvailableForReserve : $ticketIsAvailableOtherwise; 16. 17. $leftTickets = []; 18. foreach ($tickets as $ticket) { 19. if ($ticketIsAvailable[$ticket->getId()]) { 20. $leftTickets[$ticket->getId()] = $ticket; 21. } 22. } 23. 24. $allowedTickets = []; 25. foreach ($leftTickets as $ticket) { 26. if ($ticketIsAllowedForUser[$ticket->getId()]) { 27. $allowedTickets[$ticket->getId()] = $ticket; 28. } 29. } 30. 31. return $allowedTickets; 32. }
  31. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): 2.

    array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 5. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = $ticketIsAllowedForUser = []; 6. $today = new DateTimeImmutable(); 7. foreach ($tickets as $ticket) { 8. $ticketIsAvailableForReserve[$ticket->getId()] = $ticket->isOpenForSaleOn($today); 9. $ticketIsAvailableOtherwise[$ticket->getId()] = $ticket->isOpenForSaleOn($today) 10. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 11. $ticketIsAllowedForUser[$ticket->getId()] = 12. $this->ticketRepository->checkAllowed($ticket, $user); 13. } 14. 15. $ticketIsAvailable = $forReserve ? $ticketIsAvailableForReserve : $ticketIsAvailableOtherwise; 16. 17. $leftTickets = []; 18. foreach ($tickets as $ticket) { 19. if ($ticketIsAvailable[$ticket->getId()]) { 20. $leftTickets[$ticket->getId()] = $ticket; 21. } 22. } 23. 24. $allowedTickets = []; 25. foreach ($leftTickets as $ticket) { 26. if ($ticketIsAllowedForUser[$ticket->getId()]) { 27. $allowedTickets[$ticket->getId()] = $ticket; 28. } 29. } 30. 31. return $allowedTickets; 32. }
  32. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): 2.

    array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 5. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = []; 6. $today = new DateTimeImmutable(); 7. foreach ($tickets as $ticket) { 8. $ticketIsAvailableForReserve[$ticket->getId()] = $ticket->isOpenForSaleOn($today); 9. $ticketIsAvailableOtherwise[$ticket->getId()] = $ticket->isOpenForSaleOn($today) 10. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 11. } 12. 13. $ticketIsAvailable = $forReserve ? $ticketIsAvailableForReserve : $ticketIsAvailableOtherwise; 14. 15. $leftTickets = []; 16. foreach ($tickets as $ticket) { 17. if ($ticketIsAvailable[$ticket->getId()]) { 18. $leftTickets[$ticket->getId()] = $ticket; 19. } 20. } 21. 22. $allowedTickets = []; 23. foreach ($leftTickets as $ticket) { 24. if ($this->ticketRepository->checkAllowed($ticket, $user)) { 25. $allowedTickets[$ticket->getId()] = $ticket; 26. } 27. } 28. 29. return $allowedTickets; 30. }
  33. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): 2.

    array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 5. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = []; 6. $today = new DateTimeImmutable(); 7. foreach ($tickets as $ticket) { 8. $ticketIsAvailableForReserve[$ticket->getId()] = $ticket->isOpenForSaleOn($today); 9. $ticketIsAvailableOtherwise[$ticket->getId()] = $ticket->isOpenForSaleOn($today) 10. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 11. } 12. 13. $openTickets = []; 14. foreach ($tickets as $ticket) { 15. if ($ticketIsAvailableForReserve[$ticket->getId()]) { 16. $openTickets[$ticket->getId()] = $ticket; 17. } 18. } 19. 20. $ticketIsAvailable = $forReserve ? $ticketIsAvailableForReserve : $ticketIsAvailableOtherwise; 21. 22. $leftTickets = []; 23. foreach ($openTickets as $ticket) { 24. if ($ticketIsAvailable[$ticket->getId()]) { 25. $leftTickets[$ticket->getId()] = $ticket; 26. } 27. } 28. 29. $allowedTickets = []; 30. ...
  34. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): 2.

    array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 5. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = []; 6. $today = new DateTimeImmutable(); 7. foreach ($tickets as $ticket) { 8. $ticketIsAvailableForReserve[$ticket->getId()] = $ticket->isOpenForSaleOn($today); 9. $ticketIsAvailableOtherwise[$ticket->getId()] = $ticket->isOpenForSaleOn($today) 10. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 11. } 12. 13. $openTickets = []; 14. foreach ($tickets as $ticket) { 15. if ($ticketIsAvailableForReserve[$ticket->getId()]) { 16. $openTickets[$ticket->getId()] = $ticket; 17. } 18. } 19. 20. $ticketIsAvailable = $forReserve ? $ticketIsAvailableForReserve : $ticketIsAvailableOtherwise; 21. 22. $leftTickets = []; 23. foreach ($openTickets as $ticket) { 24. if ($ticketIsAvailable[$ticket->getId()]) { 25. $leftTickets[$ticket->getId()] = $ticket; 26. } 27. } 28. 29. $allowedTickets = []; 30. ...
  35. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): 2.

    array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 5. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = []; 6. $today = new DateTimeImmutable(); 7. foreach ($tickets as $ticket) { 8. $ticketIsAvailableForReserve[$ticket->getId()] = $ticket->isOpenForSaleOn($today); 9. $ticketIsAvailableOtherwise[$ticket->getId()] = $ticket->isOpenForSaleOn($today) 10. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 11. } 12. 13. $openTickets = []; 14. foreach ($tickets as $ticket) { 15. if ($ticketIsAvailableForReserve[$ticket->getId()]) { 16. $openTickets[$ticket->getId()] = $ticket; 17. } 18. } 19. 20. $leftTickets = $openTickets; 21. if (!$forReserve) { 22. $leftTickets = []; 23. foreach ($openTickets as $ticket) { 24. if ($ticketIsAvailableOtherwise[$ticket->getId()]) { 25. $leftTickets[$ticket->getId()] = $ticket; 26. } 27. } 28. } 29. 30. $allowedTickets = []; 31. ...
  36. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): 2.

    array { 3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 5. $ticketIsAvailableForReserve = $ticketIsAvailableOtherwise = []; 6. $today = new DateTimeImmutable(); 7. foreach ($tickets as $ticket) { 8. $ticketIsAvailableForReserve[$ticket->getId()] = $ticket->isOpenForSaleOn($today); 9. $ticketIsAvailableOtherwise[$ticket->getId()] = $ticket->isOpenForSaleOn($today) 10. && $this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket); 11. } 12. 13. $openTickets = []; 14. foreach ($tickets as $ticket) { 15. if ($ticketIsAvailableForReserve[$ticket->getId()]) { 16. $openTickets[$ticket->getId()] = $ticket; 17. } 18. } 19. 20. $leftTickets = $openTickets; 21. if (!$forReserve) { 22. $leftTickets = []; 23. foreach ($openTickets as $ticket) { 24. if ($ticketIsAvailableOtherwise[$ticket->getId()]) { 25. $leftTickets[$ticket->getId()] = $ticket; 26. } 27. } 28. } 29. 30. $allowedTickets = []; 31. ...
  37. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): array

    { 2. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 3. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 4. $today = new DateTimeImmutable(); 5. 6. $openTickets = []; 7. foreach ($tickets as $ticket) { 8. if ($ticket->isOpenForSaleOn($today)) { 9. $openTickets[$ticket->getId()] = $ticket; 10. } 11. } 12. 13. $leftTickets = $openTickets; 14. if (!$forReserve) { 15. $leftTickets = []; 16. foreach ($openTickets as $ticket) { 17. if ($this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket)) { 18. $leftTickets[$ticket->getId()] = $ticket; 19. } 20. } 21. } 22. 23. $allowedTickets = []; 24. foreach ($leftTickets as $ticket) { 25. if ($this->ticketRepository->checkAllowed($ticket, $user)) { 26. $allowedTickets[$ticket->getId()] = $ticket; 27. } 28. } 29. 30. return $allowedTickets; 31. }
  38. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): array

    { 2. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 3. $today = new DateTimeImmutable(); 4. 5. $openTickets = []; 6. foreach ($tickets as $ticket) { 7. if ($ticket->isOpenForSaleOn($today)) { 8. $openTickets[$ticket->getId()] = $ticket; 9. } 10. } 11. 12. $allowedTickets = []; 13. foreach ($openTickets as $ticket) { 14. if ($this->ticketRepository->checkAllowed($ticket, $user)) { 15. $allowedTickets[$ticket->getId()] = $ticket; 16. } 17. } 18. 19. if ($forReserve) { 20. return $allowedTickets; 21. } 22. 23. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 24. $leftTickets = []; 25. foreach ($allowedTickets as $ticket) { 26. if ($this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket)) { 27. $leftTickets[$ticket->getId()] = $ticket; 28. } 29. } 30. 31. return $leftTickets; 32. }
  39. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): array

    { 2. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 3. $today = new DateTimeImmutable(); 4. 5. $openTickets = []; 6. foreach ($tickets as $ticket) { 7. if ($ticket->isOpenForSaleOn($today)) { 8. $openTickets[$ticket->getId()] = $ticket; 9. } 10. } 11. 12. $allowedTickets = []; 13. foreach ($openTickets as $ticket) { 14. if ($this->ticketRepository->checkAllowed($ticket, $user)) { 15. $allowedTickets[$ticket->getId()] = $ticket; 16. } 17. } 18. 19. if ($forReserve) { 20. return $allowedTickets; 21. } 22. 23. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 24. $leftTickets = []; 25. foreach ($allowedTickets as $ticket) { 26. if ($this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket)) { 27. $leftTickets[$ticket->getId()] = $ticket; 28. } 29. } 30. 31. return $leftTickets; 32. }
  40. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): array

    { 2. $openTickets = $this->getTicketsOpenForSaleOn($meeting, new DateTimeImmutable()); 3. 4. $allowedTickets = []; 5. foreach ($openTickets as $ticket) { 6. if ($this->ticketRepository->checkAllowed($ticket, $user)) { 7. $allowedTickets[$ticket->getId()] = $ticket; 8. } 9. } 10. 11. if ($forReserve) { 12. return $allowedTickets; 13. } 14. 15. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 16. $leftTickets = []; 17. foreach ($allowedTickets as $ticket) { 18. if ($this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket)) { 19. $leftTickets[$ticket->getId()] = $ticket; 20. } 21. } 22. 23. return $leftTickets; 24. } 25. 26. private function getTicketsOpenForSaleOn(Meeting $meeting, DateTimeImmutable $date): array {...}
  41. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): array

    { 2. $openTickets = $this->getTicketsOpenForSaleOn($meeting, new DateTimeImmutable()); 3. 4. $allowedTickets = []; 5. foreach ($openTickets as $ticket) { 6. if ($this->ticketRepository->checkAllowed($ticket, $user)) { 7. $allowedTickets[$ticket->getId()] = $ticket; 8. } 9. } 10. 11. if ($forReserve) { 12. return $allowedTickets; 13. } 14. 15. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 16. $leftTickets = []; 17. foreach ($allowedTickets as $ticket) { 18. if ($this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket)) { 19. $leftTickets[$ticket->getId()] = $ticket; 20. } 21. } 22. 23. return $leftTickets; 24. } 25. 26. private function getTicketsOpenForSaleOn(Meeting $meeting, DateTimeImmutable $date): array {...}
  42. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): array

    { 2. $allowedTickets = $this->getTicketsUserCanReserve($meeting, $user); 3. 4. if ($forReserve) { 5. return $allowedTickets; 6. } 7. 8. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 9. $leftTickets = []; 10. foreach ($allowedTickets as $ticket) { 11. if ($this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket)) { 12. $leftTickets[$ticket->getId()] = $ticket; 13. } 14. } 15. 16. return $leftTickets; 17. } 18. 19. private function getTicketsOpenForSaleOn(Meeting $meeting, DateTimeImmutable $date): array {...} 20. 21. private function getTicketsUserCanReserve(Meeting $meeting, User $user): array {...}
  43. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): array

    { 2. $allowedTickets = $this->getTicketsUserCanReserve($meeting, $user); 3. 4. if ($forReserve) { 5. return $allowedTickets; 6. } 7. 8. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 9. $leftTickets = []; 10. foreach ($allowedTickets as $ticket) { 11. if ($this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket)) { 12. $leftTickets[$ticket->getId()] = $ticket; 13. } 14. } 15. 16. return $leftTickets; 17. } 18. 19. private function getTicketsOpenForSaleOn(Meeting $meeting, DateTimeImmutable $date): array {...} 20. 21. private function getTicketsUserCanReserve(Meeting $meeting, User $user): array {...}
  44. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): array

    { 2. if ($forReserve) { 3. return $this->getTicketsUserCanReserve($meeting, $user); 4. } 5. 6. $allowedTickets = $this->getTicketsUserCanReserve($meeting, $user); 7. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 8. $leftTickets = []; 9. foreach ($allowedTickets as $ticket) { 10. if ($this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket)) { 11. $leftTickets[$ticket->getId()] = $ticket; 12. } 13. } 14. 15. return $leftTickets; 16. } 17. 18. private function getTicketsOpenForSaleOn(Meeting $meeting, DateTimeImmutable $date): array {...} 19. 20. private function getTicketsUserCanReserve(Meeting $meeting, User $user): array {...}
  45. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): array

    { 2. if ($forReserve) { 3. return $this->getTicketsUserCanReserve($meeting, $user); 4. } 5. 6. $allowedTickets = $this->getTicketsUserCanReserve($meeting, $user); 7. $currentSoldPerTicket = $this->ticketRepository->getNumberOfCurrentSoldTickets($meeting); 8. $leftTickets = []; 9. foreach ($allowedTickets as $ticket) { 10. if ($this->thereAreTicketsLeftForSale($ticket, $currentSoldPerTicket)) { 11. $leftTickets[$ticket->getId()] = $ticket; 12. } 13. } 14. 15. return $leftTickets; 16. } 17. 18. private function getTicketsOpenForSaleOn(Meeting $meeting, DateTimeImmutable $date): array {...} 19. 20. private function getTicketsUserCanReserve(Meeting $meeting, User $user): array {...}
  46. 1. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): array

    { 2. if ($forReserve) { 3. return $this->getTicketsUserCanReserve($meeting, $user); 4. } 5. return $this->getTicketsUserCanPurchase($meeting, $user); 6. } 7. 8. private function getTicketsOpenForSaleOn(Meeting $meeting, DateTimeImmutable $date): array {...} 9. 10. private function getTicketsUserCanReserve(Meeting $meeting, User $user): array {...} 11. 12. private function getTicketsUserCanPurchase(Meeting $meeting, User $user): array {...}
  47. 1. /** @deprecated Use getTicketsUserCanReserve or getTicketsUserCanPurchase */ 2. public

    function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): array { 3. if ($forReserve) { 4. return $this->getTicketsUserCanReserve($meeting, $user); 5. } 6. return $this->getTicketsUserCanPurchase($meeting, $user); 7. } 8. 9. private function getTicketsOpenForSaleOn(Meeting $meeting, DateTimeImmutable $date): array {...} 10. 11. public function getTicketsUserCanReserve(Meeting $meeting, User $user): array {...} 12. 13. public function getTicketsUserCanPurchase(Meeting $meeting, User $user): array {...} OK (14 tests, 14 assertions)
  48. 1. private function getTicketsOpenForSaleOn(Meeting $meeting, DateTimeImmutable $date): 2. array {

    3. $tickets = $this->ticketRepository->getMeetingTickets($meeting); 4. $openTickets = []; 5. foreach ($tickets as $ticket) { 6. if ($ticket->isOpenForSaleOn($today)) { 7. $openTickets[$ticket->getId()] = $ticket; 8. } 9. } 10. return $openTickets; 11. }
  49. 1. final class Meeting { 2. ... 3. public function

    getTickets(): array { 4. return $this->tickets; 5. } 6. 7. public function getTicketsOpenForSaleOn(DateTimeImmutable $date): array { 8. $openTickets = []; 9. foreach ($this->tickets as $ticket) { 10. if ($ticket->ticketIsOpenForSaleOn($date)) { 11. $openTickets[$ticket->getId()] = $ticket; 12. } 13. } 14. return $openTickets; 15. } 16. } .............. 14 / 14 (100%) Time: 43 ms, Memory: 4.00MB OK (14 tests, 14 assertions)
  50. 1. final class TicketService { 2. /** @deprecated Use getPrivatelyAvailableTickets,

    getTicketsUserCanReserve or getTicketsUserCanPurchase */ 3. public function getAvailableTickets(Meeting $meeting, bool $publicOnly, User $user, 4. bool $forReserve): array {...} 5. 6. public function getPrivatelyAvailableTickets(Meeting $meeting): array {...} 7. 8. /** @deprecated Use getTicketsUserCanReserve or getTicketsUserCanPurchase */ 9. public function getPubliclyAvailableTickets(Meeting $meeting, User $user, bool $forReserve): array {...} 10. 11. public function getTicketsUserCanReserve(Meeting $meeting, User $user): array {...} 12. 13. public function getTicketsUserCanPurchase(Meeting $meeting, User $user): array {...} 14. 15. private function thereAreTicketsLeftForSale(Ticket $ticket, array $currentSoldPerTicket): bool {...} 16. }
  51. 1. public function testThatTicketsCannotBeSoldWhenMeetingHasStarted() { 2. $meeting = new Meeting(

    3. ..., 4. new Program( 5. new MeetingDuration( 6. new DateTimeImmutable('2018-02-20 19:00'), 7. new DateTimeImmutable('2018-02-20 22:00') 8. ), 9. [] 10. ), 11. [new Ticket(1, true, 0, null, null)] 12. ); 13. 14. $expected = []; 15. $actual = $meeting->getTicketsOpenForSaleOn( 16. new DateTimeImmutable('2018-02-20 20:00') 17. ); 18. 19. $this->assertEquals($expected, $actual); 20. } --- Expected +++ Actual @@ @@ Array ( + 1 => Pelshoff\Meeting\Ticket Object (...) )
  52. 1. public function getTicketsOpenForSaleOn(DateTimeImmutable $date): array { 2. if ($this->program->hasStartedOn($date))

    { 3. return []; 4. } 5. $openTickets = []; 6. foreach ($this->tickets as $ticket) { 7. if ($ticket->isOpenForSaleOn($date)) { 8. $openTickets[$ticket->getId()] = $ticket; 9. } 10. } 11. return $openTickets; 12. } ............... 15 / 15 (100%) Time: 84 ms, Memory: 4.00MB OK (15 tests, 15 assertions)
  53. Closing links https://martinfowler.com/books/refactoring.html && https://www.refactoring.com/catalog/ https://www.sandimetz.com/99bottles https://www.youtube.com/watch?v=8bZh5LMaSmE Al the Little

    Things, by Sandi Metz https://www.youtube.com/watch?v=PJjHfa5yxlU Get a Whiff of This, by Sandi Metz https://www.youtube.com/watch?v=F3DV9YDeA6Q Distill the Core Domain from your Legacy App, by Thomas Pierrain && Bruno Boucard