Clicker   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 119
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 16
eloc 55
dl 0
loc 119
ccs 53
cts 53
cp 1
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A addClick() 0 24 3
A addReferenceClick() 0 13 2
A getClicks() 0 9 2
A __construct() 0 6 1
A userHasClicked() 0 26 4
A validateClick() 0 8 4
1
<?php
2
3
/*
4
 * This file is part of the MsalsasVotingBundle package.
5
 *
6
 * (c) Manolo Salsas
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Msalsas\VotingBundle\Service;
13
14
15
use Doctrine\ORM\EntityManagerInterface;
16
use Msalsas\VotingBundle\Entity\Click;
17
use Msalsas\VotingBundle\Entity\ReferenceClicks;
18
use Symfony\Component\Finder\Exception\AccessDeniedException;
19
use Symfony\Component\HttpFoundation\Request;
20
use Symfony\Component\HttpFoundation\RequestStack;
21
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
22
use Symfony\Component\Security\Core\User\UserInterface;
23
use Symfony\Component\Translation\TranslatorInterface;
24
25
class Clicker
26
{
27
    /**
28
     * @var EntityManagerInterface
29
     */
30
    protected $em;
31
32
    /**
33
     * @var TokenStorageInterface
34
     */
35
    protected $token;
36
37
    /**
38
     * @var Request
39
     */
40
    protected $request;
41
42
    /**
43
     * @var TranslatorInterface
44
     */
45
    protected $translator;
46
47 6
    public function __construct(EntityManagerInterface $em, TokenStorageInterface $token, RequestStack $requestStack, TranslatorInterface $translator)
48
    {
49 6
        $this->em = $em;
50 6
        $this->token = $token;
51 6
        $this->request = $requestStack->getCurrentRequest();
52 6
        $this->translator = $translator;
53 6
    }
54
55 5
    public function getClicks($referenceId)
56
    {
57
        /** @var ReferenceClicks|null $referenceClicks */
58 5
        $referenceClicks = $this->em->getRepository(ReferenceClicks::class)->findOneBy(array('reference' => $referenceId));
59 5
        if (!$referenceClicks) {
60 3
            return 0;
61
        }
62
63 2
        return $referenceClicks->getClicks();
64
    }
65
66 6
    public function addClick($referenceId)
67
    {
68 6
        $user = $this->token->getToken()->getUser();
69 6
        $user = $user instanceof UserInterface ? $user : null;
70
71
        try {
72 6
            $this->validateClick($user, $referenceId);
73 3
        } catch (\Exception $e) {
74 3
            return $this->getClicks($referenceId);
75
        }
76
77 3
        $click = new Click();
78 3
        $click->setReference($referenceId);
79 3
        $click->setUser($user);
80 3
        $click->setUserIP($this->request->getClientIp());
81
82
        /** @var \Msalsas\VotingBundle\Entity\ReferenceClicks $referenceClicks */
83 3
        $referenceClicks = $this->addReferenceClick($referenceId);
84
85 3
        $this->em->persist($click);
86 3
        $this->em->persist($referenceClicks);
87 3
        $this->em->flush();
88
89 3
        return $referenceClicks->getClicks();
90
    }
91
92 6
    private function validateClick($user, $referenceId)
93
    {
94 6
        if (!$user instanceof UserInterface && !$this->request->getClientIp()) {
95 1
            throw new AccessDeniedException($this->translator->trans('msalsas_voting.errors.no_ip_defined_for_anon'));
96
        }
97
98 5
        if ($this->userHasClicked($user, $referenceId)) {
99 2
            throw new AccessDeniedException($this->translator->trans('msalsas_voting.errors.already_clicked'));
100
        }
101 3
    }
102
103 5
    private function userHasClicked($user, $referenceId)
104
    {
105 5
        $clickRepository = $this->em->getRepository(Click::class);
106
107 5
        if ($user instanceof UserInterface) {
108 3
            if ($clickRepository->findOneBy(
109
                array(
110 3
                    'user' => $user,
111 3
                    'reference' => $referenceId
112
                )
113
            )) {
114 3
                return true;
115
            }
116
        } else {
117 2
            if ($clickRepository->findOneBy(
118
                array(
119 2
                    'user' => null,
120 2
                    'userIP' => $this->request->getClientIp(),
121 2
                    'reference' => $referenceId
122
                )
123
            )) {
124 1
                return true;
125
            }
126
        }
127
128 3
        return false;
129
    }
130
131 3
    private function addReferenceClick($referenceId)
132
    {
133
        /** @var ReferenceClicks|null $referenceClicks */
134 3
        $referenceClicks = $this->em->getRepository(ReferenceClicks::class)->findOneBy(array('reference' => $referenceId));
135 3
        if ($referenceClicks) {
136 1
            $referenceClicks->addClick();
137
        } else {
138 2
            $referenceClicks = new ReferenceClicks();
139 2
            $referenceClicks->setReference($referenceId);
140 2
            $referenceClicks->addClick();
141
        }
142
143 3
        return $referenceClicks;
144
    }
145
}