PollRepository.php 2.88 KB
<?php

namespace FootyRoom\Repositories\Poll;

use MongoDB\BSON\ObjectId;
use FootyRoom\Support\MongoClient;
use MongoDB\BSON\UTCDateTime;
use FootyRoom\Support\AutoMapper;
use FootyRoom\Core\Poll\Poll;

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

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

    /**
     * Finds poll by specified id.
     *
     * @param string $pollId
     *
     * @return \FootyRoom\Core\Poll\Poll|null
     */
    public function findById($pollId)
    {
        $pollDto = $this->mongo->polls->findOne([
            '_id' => new ObjectId($pollId),
        ]);

        if (!$pollDto) {
            return null;
        }

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

        AutoMapper::setValue($poll, 'id', (string) $pollDto->_id);

        return $poll;
    }

    /**
     * Maps Poll object to array so that we can persist it.
     *
     * @param \FootyRoom\Core\Poll\Poll $poll
     *
     * @return array
     */
    protected function mapToArray(Poll $poll)
    {
        $pollDTO = [
            'userId' => $poll->getUserId(),
            'isPublished' => $poll->getIsPublished(),
        ];

        foreach ($poll->getChoices() as $key => $choice) {
            $pollDTO['choices'][$key]['id'] = $choice->getId();
            $pollDTO['choices'][$key]['text'] = $choice->getText();
            $pollDTO['choices'][$key]['image'] = $choice->getImage();
        }

        return $pollDTO;
    }

    /**
     * Create poll.
     *
     * @param \FootyRoom\Core\Poll\Poll $poll
     */
    public function create(Poll $poll)
    {
        $pollDTO = $this->mapToArray($poll);

        // Automatically expire unpublished polls after 1 day.
        $pollDTO['expireAt'] = new UTCDateTime(strtotime('+30 day') * 1000);

        $result = $this->mongo->polls->insertOne($pollDTO);

        AutoMapper::setValue($poll, 'id', (string) $result->getInsertedId());
    }

    /**
     * Update poll.
     *
     * @param \FootyRoom\Core\Poll\Poll $poll
     */
    public function update(Poll $poll)
    {
        $pollDTO = $this->mapToArray($poll);

        $this->mongo->polls->updateOne(
            ['_id' => new ObjectId($poll->getId())],
            ['$set' => [
                'choices' => $pollDTO['choices'],
                'isPublished' => $pollDTO['isPublished'],
            ]]
        );
    }

    /**
     * Marks poll as published.
     *
     * @param string $id
     */
    public function markPublished($id)
    {
        $this->mongo->polls->updateOne(
            ['_id' => new ObjectId($id)],
            ['$set' => [
                'isPublished' => true,
            ],
            '$unset' => [
                'expireAt' => 1,
            ], ]
        );
    }
}