Merge branch '3.0'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / action / PollAction.class.php
CommitLineData
e25b7b61
MW
1<?php
2namespace wcf\action;
3use wcf\system\exception\IllegalLinkException;
4use wcf\system\exception\PermissionDeniedException;
5use wcf\system\exception\SystemException;
6use wcf\system\exception\UserInputException;
7use wcf\system\poll\PollManager;
8use wcf\system\WCF;
9use wcf\util\ArrayUtil;
10use wcf\util\JSON;
11use wcf\util\StringUtil;
12
13/**
14 * Handles poll interaction.
15 *
16 * @author Alexander Ebert
c839bd49 17 * @copyright 2001-2018 WoltLab GmbH
e25b7b61 18 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
e71525e4 19 * @package WoltLabSuite\Core\Action
e25b7b61
MW
20 */
21class PollAction extends AJAXProxyAction {
22 /**
0fcfe5f6 23 * @inheritDoc
e25b7b61
MW
24 */
25 public $loginRequired = true;
26
27 /**
28 * list of option ids
7a23a706 29 * @var integer[]
e25b7b61 30 */
058cbd6a 31 public $optionIDs = [];
e25b7b61
MW
32
33 /**
34 * poll object
0ad90fc3 35 * @var \wcf\data\poll\Poll
e25b7b61
MW
36 */
37 public $poll = null;
38
39 /**
40 * poll id
41 * @var integer
42 */
43 public $pollID = 0;
44
45 /**
46 * related poll object
0ad90fc3 47 * @var \wcf\data\IPollObject
e25b7b61
MW
48 */
49 public $relatedObject = null;
50
51 /**
0fcfe5f6 52 * @inheritDoc
e25b7b61
MW
53 */
54 public function readParameters() {
55 if (!MODULE_POLL) {
56 throw new IllegalLinkException();
57 }
58
59 AbstractSecureAction::readParameters();
60
61 if (isset($_POST['actionName'])) $this->actionName = StringUtil::trim($_POST['actionName']);
62 if (isset($_POST['pollID'])) $this->pollID = intval($_POST['pollID']);
63
058cbd6a 64 $polls = PollManager::getInstance()->getPolls([$this->pollID]);
e25b7b61
MW
65 if (!isset($polls[$this->pollID])) {
66 throw new UserInputException('pollID');
67 }
68 $this->poll = $polls[$this->pollID];
69
70 // load related object
71 $this->relatedObject = PollManager::getInstance()->getRelatedObject($this->poll);
72 if ($this->relatedObject === null) {
73 if ($this->poll->objectID) {
74 throw new SystemException("Missing related object for poll id '".$this->poll->pollID."'");
75 }
76 }
77 else {
78 $this->poll->setRelatedObject($this->relatedObject);
79 }
80
81 // validate action
82 switch ($this->actionName) {
83 case 'getResult':
84 if (!$this->poll->canSeeResult()) {
85 throw new PermissionDeniedException();
86 }
87 break;
88
89 case 'getVote':
90 case 'vote':
91 if (!$this->poll->canVote()) {
92 throw new PermissionDeniedException();
93 }
94 break;
95
96 default:
97 throw new SystemException("Unknown action '".$this->actionName."'");
98 break;
99 }
100
101 if (isset($_POST['optionIDs']) && is_array($_POST['optionIDs'])) {
102 $this->optionIDs = ArrayUtil::toIntegerArray($_POST['optionIDs']);
103 if (count($this->optionIDs) > $this->poll->maxVotes) {
104 throw new PermissionDeniedException();
105 }
106
058cbd6a 107 $optionIDs = [];
e25b7b61
MW
108 foreach ($this->poll->getOptions() as $option) {
109 $optionIDs[] = $option->optionID;
110 }
111
112 foreach ($this->optionIDs as $optionID) {
113 if (!in_array($optionID, $optionIDs)) {
114 throw new PermissionDeniedException();
115 }
116 }
117 }
118 }
119
120 /**
0fcfe5f6 121 * @inheritDoc
e25b7b61
MW
122 */
123 public function execute() {
124 AbstractAction::execute();
125
058cbd6a 126 $returnValues = [
e25b7b61
MW
127 'actionName' => $this->actionName,
128 'pollID' => $this->pollID
058cbd6a 129 ];
e25b7b61
MW
130
131 switch ($this->actionName) {
132 case 'getResult':
133 $this->getResult($returnValues);
134 break;
135
136 case 'getVote':
137 $this->getVote($returnValues);
138 break;
139
140 case 'vote':
141 $this->vote($returnValues);
142 break;
143 }
144
145 $this->executed();
146
147 // send JSON-encoded response
148 header('Content-type: application/json');
149 echo JSON::encode($returnValues);
150 exit;
151 }
152
153 /**
154 * Renders the result template.
ac52543a
MS
155 *
156 * @param array $returnValues
e25b7b61
MW
157 */
158 public function getResult(array &$returnValues) {
058cbd6a 159 WCF::getTPL()->assign([
e25b7b61 160 'poll' => $this->poll
058cbd6a 161 ]);
e25b7b61
MW
162
163 $returnValues['resultTemplate'] = WCF::getTPL()->fetch('pollResult');
164 }
165
166 /**
167 * Renders the vote template.
ac52543a
MS
168 *
169 * @param array $returnValues
e25b7b61
MW
170 */
171 public function getVote(array &$returnValues) {
058cbd6a 172 WCF::getTPL()->assign([
e25b7b61 173 'poll' => $this->poll
058cbd6a 174 ]);
e25b7b61
MW
175
176 $returnValues['voteTemplate'] = WCF::getTPL()->fetch('pollVote');
177 }
178
179 /**
180 * Adds a user vote.
181 *
7a23a706 182 * @param mixed[] $returnValues
e25b7b61
MW
183 */
184 protected function vote(array &$returnValues) {
058cbd6a 185 $pollAction = new \wcf\data\poll\PollAction([$this->poll], 'vote', ['optionIDs' => $this->optionIDs]);
e25b7b61
MW
186 $pollAction->executeAction();
187
188 // update poll object
058cbd6a 189 $polls = PollManager::getInstance()->getPolls([$this->pollID]);
e25b7b61
MW
190 $this->poll = $polls[$this->pollID];
191 if ($this->relatedObject !== null) {
192 $this->poll->setRelatedObject($this->relatedObject);
193 }
194
195 // render result template
196 $this->getResult($returnValues);
197
198 // render vote template if votes are changeable
199 if ($this->poll->isChangeable) {
200 $this->getVote($returnValues);
201 }
202
63b9817b 203 $returnValues['canVote'] = $this->poll->isChangeable ? 1 : 0;
e25b7b61
MW
204 }
205}