user = $user; $this->polls = new PollRepo; } private function getPollHtml(int $poll): string { return Router::i()->execute("/poll$poll", "SAPI"); } function vote(int $pollId, string $options, callable $resolve, callable $reject): void { $poll = $this->polls->get($pollId); if(!$poll) { $reject("Poll not found"); return; } try { $options = explode(",", $options); $poll->vote($this->user, $options); } catch(AlreadyVotedException $ex) { $reject("Poll state changed: user has already voted."); return; } catch(PollLockedException $ex) { $reject("Poll state changed: poll has ended."); return; } catch(InvalidOptionException $ex) { $reject("Foreign options passed."); return; } catch(UnexpectedValueException $ex) { $reject("Too much options passed."); return; } $resolve(["html" => $this->getPollHtml($pollId)]); } function unvote(int $pollId, callable $resolve, callable $reject): void { $poll = $this->polls->get($pollId); if(!$poll) { $reject("Poll not found"); return; } try { $poll->revokeVote($this->user); } catch(PollLockedException $ex) { $reject("Votes can't be revoked from this poll."); return; } $resolve(["html" => $this->getPollHtml($pollId)]); } }