Commit | Line | Data |
---|---|---|
e25b7b61 MW |
1 | <?php |
2 | namespace wcf\action; | |
3 | use wcf\system\exception\IllegalLinkException; | |
4 | use wcf\system\exception\PermissionDeniedException; | |
5 | use wcf\system\exception\SystemException; | |
6 | use wcf\system\exception\UserInputException; | |
7 | use wcf\system\poll\PollManager; | |
8 | use wcf\system\WCF; | |
9 | use wcf\util\ArrayUtil; | |
10 | use wcf\util\JSON; | |
11 | use 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 | */ |
21 | class 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 | } |