From f34fb9c7b958a1d79d56d3b1f9069dc25796d238 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 9 Nov 2020 17:43:10 +0000 Subject: [PATCH] [Poll] Added variable num of options not sure if it is the right way to do it --- plugins/PollPlugin/Controller/NewPoll.php | 56 ++++++++++++------- plugins/PollPlugin/Controller/RespondPoll.php | 48 ++++++++++------ plugins/PollPlugin/Controller/ShowPoll.php | 16 +++++- plugins/PollPlugin/Forms/NewPollForm.php | 7 +++ plugins/PollPlugin/Forms/PollResponseForm.php | 7 +++ plugins/PollPlugin/PollPlugin.php | 14 ++++- src/Entity/Poll.php | 48 +++++++++++++--- src/Entity/PollResponse.php | 12 +++- 8 files changed, 158 insertions(+), 50 deletions(-) diff --git a/plugins/PollPlugin/Controller/NewPoll.php b/plugins/PollPlugin/Controller/NewPoll.php index c30a32ed82..a210d2c5d6 100644 --- a/plugins/PollPlugin/Controller/NewPoll.php +++ b/plugins/PollPlugin/Controller/NewPoll.php @@ -22,39 +22,53 @@ namespace Plugin\PollPlugin\Controller; use App\Core\DB\DB; -use App\Core\Form; -use function App\Core\I18n\_m; use App\Entity\Poll; use App\Util\Common; +use App\Util\Exception\InvalidFormException; use App\Util\Exception\RedirectException; use Plugin\PollPlugin\Forms\NewPollForm; -use Symfony\Component\Form\Extension\Core\Type\NumberType; -use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\HttpFoundation\Request; +const MAX_OPTS = 5; +const MIN_OPTS = 2; + class NewPoll { - private int $numOptions = 3; - - public function newpoll(Request $request) + /** + * Create poll + * + * @param Request $request + * @param int $num num of options + * + * @throws InvalidFormException invalid form + * @throws RedirectException + * @throws \App\Util\Exception\NoLoggedInUser user is not logged in + * + * @return array template + */ + public function newpoll(Request $request, int $num) { - $user = Common::ensureLoggedIn(); - - $form = NewPollForm::make($this->numOptions); + $user = Common::ensureLoggedIn(); + $numOptions = min(max($num,MIN_OPTS),MAX_OPTS); + $form = NewPollForm::make($numOptions); $form->handleRequest($request); $opt = []; if ($form->isSubmitted()) { - $data = $form->getData(); - //var_dump($data); - $question = $data['Question']; - for ($i = 1; $i <= $this->numOptions; ++$i) { - array_push($opt,$data['Option_' . $i]); + if ($form->isValid()) { + $data = $form->getData(); + //var_dump($data); + $question = $data['Question']; + for ($i = 1; $i <= $numOptions; ++$i) { + array_push($opt, $data['Option_' . $i]); + } + $poll = Poll::make($user->getId(), $question, $opt); + DB::persist($poll); + DB::flush(); + //var_dump($testPoll); + throw new RedirectException('showpoll', ['id' => $poll->getId()]); + } else { + throw new InvalidFormException(); } - $poll = Poll::make($question,$opt); - DB::persist($poll); - DB::flush(); - //var_dump($testPoll); - throw new RedirectException('showpoll', ['id' => $poll->getId()]); } // testing @@ -77,7 +91,7 @@ class NewPoll if ($form->isSubmitted()) { $data = $form->getData(); - $this->numOptions = $data['Num_of_Questions']; + NewPoll::numOptions = $data['Num_of_Questions']; var_dump($data); } return ['_template' => 'Poll/newpoll.html.twig', 'form' => $form->createView()]; diff --git a/plugins/PollPlugin/Controller/RespondPoll.php b/plugins/PollPlugin/Controller/RespondPoll.php index f4e3e53672..da38c04f1a 100644 --- a/plugins/PollPlugin/Controller/RespondPoll.php +++ b/plugins/PollPlugin/Controller/RespondPoll.php @@ -26,8 +26,9 @@ use App\Entity\Poll; use App\Entity\PollResponse; use App\Util\Common; use App\Util\Exception\InvalidFormException; +use App\Util\Exception\NotFoundException; use App\Util\Exception\RedirectException; -use League\Uri\Exception; +use App\Util\Exception\ServerException; use Plugin\PollPlugin\Forms\PollResponseForm; use Symfony\Component\HttpFoundation\Request; @@ -35,6 +36,17 @@ class RespondPoll { /** * Handle poll response + * + * @param Request $request + * @param string $id poll id + * + * @throws InvalidFormException invalid form + * @throws NotFoundException poll does not exist + * @throws RedirectException + * @throws ServerException User already responded to poll + * @throws \App\Util\Exception\NoLoggedInUser User is not logged in + * + * @return array template */ public function respondpoll(Request $request, string $id) { @@ -43,8 +55,8 @@ class RespondPoll $poll = Poll::getFromId((int) $id); //var_dump($poll); - if ($poll == null) {//|| !$poll->isVisibleTo($user)) { todo - throw new Exception(); //?fix + if ($poll == null) { + throw new NotFoundException('Poll does not exist'); } $question = $poll->getQuestion(); // echo $question; @@ -55,21 +67,25 @@ class RespondPoll $form->handleRequest($request); if ($form->isSubmitted()) { - $data = $form->getData(); - $selection = array_values($data)[1]; - //echo $selection; - if (!$poll->isValidSelection($selection)) { + if ($form->isValid()) { + $data = $form->getData(); + $selection = array_values($data)[1]; + //echo $selection; + if (!$poll->isValidSelection($selection)) { + throw new InvalidFormException(); + } + if (PollResponse::exits($poll->getId(), $user->getId())) { + throw new ServerException('User already responded to poll'); + } + + $pollResponse = PollResponse::create(['poll_id' => $poll->getId(), 'gsactor_id' => $user->getId(), 'selection' => $selection]); + DB::persist($pollResponse); + DB::flush(); + //var_dump($pollResponse); + throw new RedirectException('showpoll', ['id' => $poll->getId()]); + } else { throw new InvalidFormException(); } - if (PollResponse::exits($poll->getId(),$user->getId())) { - throw new Exception(); - } - - $pollResponse = PollResponse::create(['poll_id' => $poll->getId(), 'gsactor_id' => $user->getId(), 'selection' => $selection]); - DB::persist($pollResponse); - DB::flush(); - //var_dump($pollResponse); - throw new RedirectException('showpoll', ['id' => $poll->getId()]); } return ['_template' => 'Poll/respondpoll.html.twig', 'question' => $question, 'form' => $form->createView()]; diff --git a/plugins/PollPlugin/Controller/ShowPoll.php b/plugins/PollPlugin/Controller/ShowPoll.php index 442bb981cd..1ef691b33f 100644 --- a/plugins/PollPlugin/Controller/ShowPoll.php +++ b/plugins/PollPlugin/Controller/ShowPoll.php @@ -23,10 +23,22 @@ namespace Plugin\PollPlugin\Controller; use App\Entity\Poll; use App\Util\Common; +use App\Util\Exception\NotFoundException; use Symfony\Component\HttpFoundation\Request; class ShowPoll { + /** + * Show poll + * + * @param Request $request + * @param string $id poll id + * + * @throws NotFoundException poll does not exist + * @throws \App\Util\Exception\NoLoggedInUser user is not logged in + * + * @return array Template + */ public function showpoll(Request $request, string $id) { $user = Common::ensureLoggedIn(); @@ -34,8 +46,8 @@ class ShowPoll $poll = Poll::getFromId((int) $id); //var_dump($poll); - if ($poll == null) {//|| !$poll->isVisibleTo($user)) { todo - throw new NoSuchPollException(); //? + if ($poll == null) { + throw new NotFoundException('Poll does not exist'); } return ['_template' => 'Poll/showpoll.html.twig', 'poll' => $poll]; diff --git a/plugins/PollPlugin/Forms/NewPollForm.php b/plugins/PollPlugin/Forms/NewPollForm.php index b9fd410919..703f619a04 100644 --- a/plugins/PollPlugin/Forms/NewPollForm.php +++ b/plugins/PollPlugin/Forms/NewPollForm.php @@ -30,6 +30,13 @@ use Symfony\Component\Form\Form as SymfForm; const MAX_OPT = 5; class NewPollForm extends Form { + /** + * Creates a form with variable num of fields + * + * @param int $optionNum + * + * @return SymfForm + */ public static function make(int $optionNum): SymfForm { $optionNum = min(MAX_OPT,$optionNum); diff --git a/plugins/PollPlugin/Forms/PollResponseForm.php b/plugins/PollPlugin/Forms/PollResponseForm.php index 2ff5765335..65758870fc 100644 --- a/plugins/PollPlugin/Forms/PollResponseForm.php +++ b/plugins/PollPlugin/Forms/PollResponseForm.php @@ -29,6 +29,13 @@ use Symfony\Component\Form\Form as SymfForm; class PollResponseForm extends Form { + /** + * Creates a radio form with the options given + * + * @param array $opts options + * + * @return SymfForm + */ public static function make(array $opts): SymfForm { $formOptions = []; diff --git a/plugins/PollPlugin/PollPlugin.php b/plugins/PollPlugin/PollPlugin.php index 5bf7f60258..57581a9268 100644 --- a/plugins/PollPlugin/PollPlugin.php +++ b/plugins/PollPlugin/PollPlugin.php @@ -22,7 +22,9 @@ namespace Plugin\PollPlugin; use App\Core\Event; use App\Core\Module; +use App\Core\Router\RouteLoader; use Plugin\PollPlugin\Entity\Poll; +use Symfony\Bundle\FrameworkBundle\Controller\RedirectController; const ID_FMT = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'; @@ -61,12 +63,20 @@ class PollPlugin extends Module } */ - public function onAddRoute($r) + /** + * Map URLs to actions + * + * @param RouteLoader $r + * + * @return bool hook value; true means continue processing, false means stop. + */ + public function onAddRoute(RouteLoader $r): bool { - $r->connect('newpoll', 'main/poll/new', [Controller\NewPoll::class, 'newpoll']); + $r->connect('newpollnum', 'main/poll/new/{num<\\d*>}', [Controller\NewPoll::class, 'newpoll']); //$r->connect('showpoll', 'main/poll/:{id<' . ID_FMT . '>}' , [Controller\ShowPoll::class, 'showpoll']); //doesnt work $r->connect('showpoll', 'main/poll/{id<\\d*>}',[Controller\ShowPoll::class, 'showpoll']); $r->connect('respondpoll', 'main/poll/{id<\\d*>}/respond',[Controller\RespondPoll::class, 'respondpoll']); + $r->connect('newpoll', 'main/poll/new', RedirectController::class, ['defaults' => ['route' => 'newpollnum', 'num' => 3]]); return Event::next; } diff --git a/src/Entity/Poll.php b/src/Entity/Poll.php index 82c8e7d393..4249eeb636 100644 --- a/src/Entity/Poll.php +++ b/src/Entity/Poll.php @@ -106,7 +106,9 @@ class Poll extends Entity // }}} Autocode /** - * The One True Thingy that must be defined and declared. + * Entity schema definition + * + * @return array schema definition */ public static function schemaDef(): array { @@ -129,17 +131,38 @@ class Poll extends Entity ]; } + /** + * Get poll object from its id + * + * @param int $id + * + * @return null|static + */ public static function getFromId(int $id): ?self { return DB::find('poll', ['id' => $id]); } - public static function make(string $question, array $opt): self + /** + * Make new poll object + * + * @param int $gsactorId + * @param string $question + * @param array $opt poll options + * + * @return static poll object + */ + public static function make(int $gsactorId, string $question, array $opt): self { $options = implode("\n",$opt); - return self::create(['question' => $question, 'options' => $options]); + return self::create(['gsactor_id' => $gsactorId, 'question' => $question, 'options' => $options]); } + /** + * Gets options in array format + * + * @return array of options + */ public function getOptionsArr(): array { return explode("\n", $this->options); @@ -163,18 +186,27 @@ class Poll extends Entity return true; } + /** + * Counts responses from each option from a poll object, stores them into an array + * + * @return array with question and num of responses + */ public function countResponses(): array { $responses = []; $options = $this->getOptionsArr(); - for ($i = 1; $i <= count($options); ++$i) { - $responses[$options[$i - 1]] = $count = DB::dql('select count(pr) from App\Entity\Poll p, App\Entity\PollResponse pr + for ($i = 0; $i < count($options); ++$i) { + $responses[$options[$i]] = DB::dql('select count(pr) from App\Entity\Poll p, App\Entity\PollResponse pr where pr.poll_id = :id and pr.selection = :selection', - ['id' => $this->id, 'selection' => $i])[0][1] / $this->id; //todo: fix + ['id' => $this->id, 'selection' => $i + 1])[0][1] / $this->id; //todo: fix + + /* + var_dump(DB::dql('select count(pr) from App\Entity\Poll p, App\Entity\PollResponse pr + where pr.poll_id = :id and pr.selection = :selection', + ['id' => $this->id, 'selection' => $i + 1])[0][1]); + */ } - //echo var_dump($count); - //var_dump($responses); return $responses; } diff --git a/src/Entity/PollResponse.php b/src/Entity/PollResponse.php index 5e0fdfcb46..3cf2680677 100644 --- a/src/Entity/PollResponse.php +++ b/src/Entity/PollResponse.php @@ -105,7 +105,9 @@ class PollResponse extends Entity // }}} Autocode /** - * The One True Thingy that must be defined and declared. + * Entity schema definition + * + * @return array schema definition */ public static function schemaDef() { @@ -134,6 +136,14 @@ class PollResponse extends Entity ]; } + /** + * Checks if a user already responded to the poll + * + * @param int $pollId + * @param int $gsactorId user + * + * @return bool + */ public static function exits(int $pollId, int $gsactorId): bool { $res = DB::dql('select pr from App\Entity\PollResponse pr