PollQueryHandler.php 1.68 KB
<?php

namespace FootyRoom\Queries\Poll;

use MongoDB\BSON\ObjectId;
use FootyRoom\Support\MongoClient;
use FootyRoom\Support\AutoMapper;
use FootyRoom\Queries\VoteQuery;

class PollQueryHandler
{
    /**
     * @var \FootyRoom\Support\MongoClient
     */
    protected $mongo;

    /**
     * Constructor.
     *
     * @param \FootyRoom\Support\MongoClient $mongo
     */
    public function __construct(MongoClient $mongo, VoteQuery $voteQuery)
    {
        $this->mongo = $mongo->footyroom;
        $this->voteQuery = $voteQuery;
    }

    /**
     * Query handler.
     *
     * @param \FootyRoom\Queries\Poll\PollQuery $query
     *
     * @return \FootyRoom\Queries\Poll\Poll|null
     */
    public function handle(PollQuery $query)
    {
        $queryParams = [
            '_id' => new ObjectId($query->getPollId()),
        ];

        $pollDto = $this->mongo->polls->findOne($queryParams, []);

        $poll = AutoMapper::map($pollDto, Poll::class);

        $poll->id = (string) $pollDto->_id;

        /**
         * Get poll results.
         */
        $aggregate = $this->voteQuery->aggregate('poll-'.$query->getPollId());

        $poll->totalVotes = $aggregate->totalVotes ?? 0;
        $poll->maxVotes = $aggregate->maxVotes ?? 0;

        $votesByChoiceId = [];

        if (isset($aggregate->votes)) {
            foreach ($aggregate->votes as $vote) {
                if (isset($vote->value)) {
                    $votesByChoiceId[$vote->value] = $vote->votes;
                }
            }
        }

        foreach ($poll->choices as $choice) {
            $choice->votes = isset($votesByChoiceId[$choice->id]) ? $votesByChoiceId[$choice->id] : 0;
        }

        return $poll;
    }
}