VoteService::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 8
c 0
b 0
f 0
dl 0
loc 18
ccs 0
cts 13
cp 0
rs 10
cc 1
nc 1
nop 8
crap 2

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2017 Vinzenz Rosenkranz <[email protected]>
4
 *
5
 * @author René Gieling <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 *  This program is free software: you can redistribute it and/or modify
10
 *  it under the terms of the GNU Affero General Public License as
11
 *  published by the Free Software Foundation, either version 3 of the
12
 *  License, or (at your option) any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU Affero General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU Affero General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\Polls\Service;
25
26
use OCP\AppFramework\Db\DoesNotExistException;
27
use OCA\Polls\Exceptions\NotAuthorizedException;
28
use OCA\Polls\Exceptions\VoteLimitExceededException;
29
30
use OCA\Polls\Db\Log;
31
use OCA\Polls\Db\OptionMapper;
32
use OCA\Polls\Db\VoteMapper;
33
use OCA\Polls\Db\PollMapper;
34
use OCA\Polls\Db\Vote;
35
use OCA\Polls\Db\Watch;
36
use OCA\Polls\Model\Acl;
37
38
class VoteService {
39
40
	/** @var Acl */
41
	private $acl;
42
43
	/** @var AnonymizeService */
44
	private $anonymizer;
45
46
	/** @var LogService */
47
	private $logService;
48
49
	/** @var OptionMapper */
50
	private $optionMapper;
51
52
	/** @var PollMapper */
53
	private $pollMapper;
54
55
	/** @var Vote */
56
	private $vote;
57
58
	/** @var VoteMapper */
59
	private $voteMapper;
60
61
	/** @var WatchService */
62
	private $watchService;
63
64
65
	public function __construct(
66
		Acl $acl,
67
		AnonymizeService $anonymizer,
68
		LogService $logService,
69
		OptionMapper $optionMapper,
70
		PollMapper $pollMapper,
71
		Vote $vote,
72
		VoteMapper $voteMapper,
73
		WatchService $watchService
74
	) {
75
		$this->acl = $acl;
76
		$this->anonymizer = $anonymizer;
77
		$this->logService = $logService;
78
		$this->optionMapper = $optionMapper;
79
		$this->pollMapper = $pollMapper;
80
		$this->vote = $vote;
81
		$this->voteMapper = $voteMapper;
82
		$this->watchService = $watchService;
83
	}
84
85
	/**
86
	 * Read all votes of a poll based on the poll id and return list as array
87
	 */
88
	public function list(int $pollId = 0, string $token = ''): array {
89
		if ($token) {
90
			$this->acl->setToken($token);
91
		} else {
92
			$this->acl->setPollId($pollId)->request(Acl::PERMISSION_VIEW);
93
		}
94
95
		try {
96
			if (!$this->acl->isAllowed(Acl::PERMISSION_SEE_RESULTS)) {
97
				return $this->voteMapper->findByPollAndUser($this->acl->getpollId(), $this->acl->getUserId());
98
			} elseif (!$this->acl->isAllowed(Acl::PERMISSION_SEE_USERNAMES)) {
99
				$this->anonymizer->set($this->acl->getpollId(), $this->acl->getUserId());
100
				return $this->anonymizer->getVotes();
101
			} else {
102
				return $this->voteMapper->findByPoll($this->acl->getpollId());
103
			}
104
		} catch (DoesNotExistException $e) {
105
			return [];
106
		}
107
	}
108
109
	private function checkLimits(int $optionId, string $userId):void {
110
		$option = $this->optionMapper->find($optionId);
111
		$poll = $this->pollMapper->find($option->getPollId());
112
113
		// check, if the optionlimit is reached or exceeded, if one is set
114
		if ($poll->getOptionLimit() > 0) {
115
			if ($poll->getOptionLimit() <= count($this->voteMapper->getYesVotesByOption($option->getPollId(), $option->getPollOptionText()))) {
116
				throw new VoteLimitExceededException;
117
			}
118
		}
119
120
		// check if the votelimit for the user is reached or exceeded, if one is set
121
		if ($poll->getVoteLimit() > 0) {
122
			$pollOptionTexts = [];
123
			$votecount = 0;
124
125
			$options = $this->optionMapper->findByPoll($option->getPollId());
126
			$votes = $this->voteMapper->getYesVotesByParticipant($option->getPollId(), $userId);
127
128
			// Only count votes, which match to an actual existing option.
129
			// Explanation: If an option is deleted, the corresponding votes are not deleted.
130
131
			// create an array of pollOptionTexts
132
			foreach ($options as $element) {
133
				$pollOptionTexts[] = $element->getPollOptionText();
134
			}
135
136
			// only count relevant votes for the limit
137
			foreach ($votes as $vote) {
138
				if (in_array($vote->getVoteOptionText(), $pollOptionTexts)) {
139
					$votecount++;
140
				}
141
			}
142
			if ($poll->getVoteLimit() <= $votecount) {
143
				throw new VoteLimitExceededException;
144
			}
145
		}
146
	}
147
148
	/**
149
	 * Set vote
150
	 */
151
	public function set(int $optionId, string $setTo, string $token = ''): Vote {
152
		$option = $this->optionMapper->find($optionId);
153
154
		if ($token) {
155
			$this->acl->setToken($token)->request(Acl::PERMISSION_VOTE);
156
			if (intval($option->getPollId()) !== $this->acl->getPollId()) {
157
				throw new NotAuthorizedException;
158
			}
159
		} else {
160
			$this->acl->setPollId($option->getPollId())->request(Acl::PERMISSION_VOTE);
161
		}
162
163
		if ($setTo === 'yes') {
164
			$this->checkLimits($optionId, $this->acl->getUserId());
165
		}
166
167
		try {
168
			$this->vote = $this->voteMapper->findSingleVote($this->acl->getPollId(), $option->getPollOptionText(), $this->acl->getUserId());
169
			$this->vote->setVoteAnswer($setTo);
170
			$this->voteMapper->update($this->vote);
171
		} catch (DoesNotExistException $e) {
172
			// Vote does not exist, insert as new Vote
173
			$this->vote = new Vote();
174
175
			$this->vote->setPollId($this->acl->getPollId());
176
			$this->vote->setUserId($this->acl->getUserId());
177
			$this->vote->setVoteOptionText($option->getPollOptionText());
178
			$this->vote->setVoteOptionId($option->getId());
179
			$this->vote->setVoteAnswer($setTo);
180
			$this->voteMapper->insert($this->vote);
181
		}
182
		$this->logService->setLog($this->vote->getPollId(), Log::MSG_ID_SETVOTE, $this->vote->getUserId());
183
		$this->watchService->writeUpdate($this->vote->getPollId(), Watch::OBJECT_VOTES);
184
		return $this->vote;
185
	}
186
187
	/**
188
	 * Remove user from poll
189
	 */
190
	public function delete(int $pollId, string $userId): string {
191
		$this->acl->setPollId($pollId)->request(Acl::PERMISSION_EDIT);
192
		$this->voteMapper->deleteByPollAndUser($pollId, $userId);
193
		$this->watchService->writeUpdate($pollId, Watch::OBJECT_VOTES);
194
		return $userId;
195
	}
196
}
197