VSVverkeerskunde/gvq-api

View on GitHub
src/Contest/Service/ContestService.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php declare(strict_types=1);

namespace VSV\GVQ_API\Contest\Service;

use Ramsey\Uuid\UuidInterface;
use VSV\GVQ_API\Contest\Models\ContestParticipation;
use VSV\GVQ_API\Contest\Models\ContestParticipations;
use VSV\GVQ_API\Contest\Repositories\ContestParticipationRepository;
use VSV\GVQ_API\Question\ValueObjects\Year;
use VSV\GVQ_API\Quiz\Repositories\QuestionResultRepository;
use VSV\GVQ_API\Quiz\Repositories\QuizRepository;
use VSV\GVQ_API\Quiz\ValueObjects\QuizChannel;

class ContestService
{
    /**
     * @var QuestionResultRepository
     */
    private $questionResultRepository;

    /**
     * @var QuizRepository
     */
    private $quizRepository;

    /**
     * @var ContestParticipationRepository
     */
    private $contestParticipationRepository;

    /**
     * @var bool
     */
    private $closed;

    /**
     * @param QuestionResultRepository $questionResultRepository
     * @param QuizRepository $quizRepository
     * @param ContestParticipationRepository $contestParticipationRepository
     * @param bool $closed
     */
    public function __construct(
        QuestionResultRepository $questionResultRepository,
        QuizRepository $quizRepository,
        ContestParticipationRepository $contestParticipationRepository,
        bool $closed = false
    ) {
        $this->questionResultRepository = $questionResultRepository;
        $this->quizRepository = $quizRepository;
        $this->contestParticipationRepository = $contestParticipationRepository;
        $this->closed = $closed;
    }

    /**
     * @return ContestParticipations|null
     */
    public function getAll(): ?ContestParticipations
    {
        return $this->contestParticipationRepository->getAll();
    }

    /**
     * @return \Traversable
     */
    public function getTraversableContestParticipations(): \Traversable
    {
        return $this->contestParticipationRepository->getAllAsTraversable();
    }

    /**
     * @return \Traversable
     */
    public function getContestParticipantsInTeam(UuidInterface $teamId): \Traversable
    {
        return $this->contestParticipationRepository->getParticipantsInTeam($teamId);
    }

    /**
     * Can only participate if 7 or more and no previous participation for given channel.
     *
     * @param Year $year
     * @param UuidInterface $quizId
     * @return bool
     */
    public function canParticipate(Year $year, UuidInterface $quizId): bool
    {
        if ($this->closed) {
            return false;
        }

        $questionResult = $this->questionResultRepository->getById($quizId);
        if ($questionResult->getScore() < 7) {
            return false;
        }

        $quiz = $this->quizRepository->getById($quizId);
        if (!$quiz->getParticipant()) {
            return false;
        }

        return true;
    }

    public function hasParticipatedBefore(Year $year, UuidInterface $quizId): bool
    {
        $quiz = $this->quizRepository->getById($quizId);
        $channel = $quiz->getChannel();
        if ($channel->toNative() !== QuizChannel::LEAGUE) {
            $channel = new QuizChannel(QuizChannel::INDIVIDUAL);
        }
        $contestParticipation = $this->contestParticipationRepository->getByYearAndEmailAndChannel(
            $year,
            $quiz->getParticipant()->getEmail(),
            $channel
        );

        return $contestParticipation !== null;
    }

    /**
     * @param ContestParticipation $contestParticipation
     */
    public function save(ContestParticipation $contestParticipation): void
    {
        if ($this->closed) {
            return;
        }

        $existingParticipation = $this->contestParticipationRepository->getByYearAndEmailAndChannel(
            $contestParticipation->getYear(),
            $contestParticipation->getContestParticipant()->getEmail(),
            $contestParticipation->getChannel()
        );

        if ($existingParticipation === null) {
            $this->contestParticipationRepository->save($contestParticipation);
        }
    }
}