[Poll] Added variable num of options

not sure if it is the right way to do it
This commit is contained in:
Daniel 2020-11-09 17:43:10 +00:00 committed by Hugo Sales
parent cdbf7da8be
commit f34fb9c7b9
Signed by: someonewithpc
GPG Key ID: 7D0C7EAFC9D835A0
8 changed files with 158 additions and 50 deletions

View File

@ -22,39 +22,53 @@
namespace Plugin\PollPlugin\Controller; namespace Plugin\PollPlugin\Controller;
use App\Core\DB\DB; use App\Core\DB\DB;
use App\Core\Form;
use function App\Core\I18n\_m;
use App\Entity\Poll; use App\Entity\Poll;
use App\Util\Common; use App\Util\Common;
use App\Util\Exception\InvalidFormException;
use App\Util\Exception\RedirectException; use App\Util\Exception\RedirectException;
use Plugin\PollPlugin\Forms\NewPollForm; 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; use Symfony\Component\HttpFoundation\Request;
const MAX_OPTS = 5;
const MIN_OPTS = 2;
class NewPoll class NewPoll
{ {
private int $numOptions = 3; /**
* Create poll
public function newpoll(Request $request) *
* @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(); $user = Common::ensureLoggedIn();
$numOptions = min(max($num,MIN_OPTS),MAX_OPTS);
$form = NewPollForm::make($this->numOptions); $form = NewPollForm::make($numOptions);
$form->handleRequest($request); $form->handleRequest($request);
$opt = []; $opt = [];
if ($form->isSubmitted()) { if ($form->isSubmitted()) {
$data = $form->getData(); if ($form->isValid()) {
//var_dump($data); $data = $form->getData();
$question = $data['Question']; //var_dump($data);
for ($i = 1; $i <= $this->numOptions; ++$i) { $question = $data['Question'];
array_push($opt,$data['Option_' . $i]); 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 // testing
@ -77,7 +91,7 @@ class NewPoll
if ($form->isSubmitted()) if ($form->isSubmitted())
{ {
$data = $form->getData(); $data = $form->getData();
$this->numOptions = $data['Num_of_Questions']; NewPoll::numOptions = $data['Num_of_Questions'];
var_dump($data); var_dump($data);
} }
return ['_template' => 'Poll/newpoll.html.twig', 'form' => $form->createView()]; return ['_template' => 'Poll/newpoll.html.twig', 'form' => $form->createView()];

View File

@ -26,8 +26,9 @@ use App\Entity\Poll;
use App\Entity\PollResponse; use App\Entity\PollResponse;
use App\Util\Common; use App\Util\Common;
use App\Util\Exception\InvalidFormException; use App\Util\Exception\InvalidFormException;
use App\Util\Exception\NotFoundException;
use App\Util\Exception\RedirectException; use App\Util\Exception\RedirectException;
use League\Uri\Exception; use App\Util\Exception\ServerException;
use Plugin\PollPlugin\Forms\PollResponseForm; use Plugin\PollPlugin\Forms\PollResponseForm;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -35,6 +36,17 @@ class RespondPoll
{ {
/** /**
* Handle poll response * 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) public function respondpoll(Request $request, string $id)
{ {
@ -43,8 +55,8 @@ class RespondPoll
$poll = Poll::getFromId((int) $id); $poll = Poll::getFromId((int) $id);
//var_dump($poll); //var_dump($poll);
if ($poll == null) {//|| !$poll->isVisibleTo($user)) { todo if ($poll == null) {
throw new Exception(); //?fix throw new NotFoundException('Poll does not exist');
} }
$question = $poll->getQuestion(); $question = $poll->getQuestion();
// echo $question; // echo $question;
@ -55,21 +67,25 @@ class RespondPoll
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted()) { if ($form->isSubmitted()) {
$data = $form->getData(); if ($form->isValid()) {
$selection = array_values($data)[1]; $data = $form->getData();
//echo $selection; $selection = array_values($data)[1];
if (!$poll->isValidSelection($selection)) { //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(); 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()]; return ['_template' => 'Poll/respondpoll.html.twig', 'question' => $question, 'form' => $form->createView()];

View File

@ -23,10 +23,22 @@ namespace Plugin\PollPlugin\Controller;
use App\Entity\Poll; use App\Entity\Poll;
use App\Util\Common; use App\Util\Common;
use App\Util\Exception\NotFoundException;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
class ShowPoll 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) public function showpoll(Request $request, string $id)
{ {
$user = Common::ensureLoggedIn(); $user = Common::ensureLoggedIn();
@ -34,8 +46,8 @@ class ShowPoll
$poll = Poll::getFromId((int) $id); $poll = Poll::getFromId((int) $id);
//var_dump($poll); //var_dump($poll);
if ($poll == null) {//|| !$poll->isVisibleTo($user)) { todo if ($poll == null) {
throw new NoSuchPollException(); //? throw new NotFoundException('Poll does not exist');
} }
return ['_template' => 'Poll/showpoll.html.twig', 'poll' => $poll]; return ['_template' => 'Poll/showpoll.html.twig', 'poll' => $poll];

View File

@ -30,6 +30,13 @@ use Symfony\Component\Form\Form as SymfForm;
const MAX_OPT = 5; const MAX_OPT = 5;
class NewPollForm extends Form class NewPollForm extends Form
{ {
/**
* Creates a form with variable num of fields
*
* @param int $optionNum
*
* @return SymfForm
*/
public static function make(int $optionNum): SymfForm public static function make(int $optionNum): SymfForm
{ {
$optionNum = min(MAX_OPT,$optionNum); $optionNum = min(MAX_OPT,$optionNum);

View File

@ -29,6 +29,13 @@ use Symfony\Component\Form\Form as SymfForm;
class PollResponseForm extends Form 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 public static function make(array $opts): SymfForm
{ {
$formOptions = []; $formOptions = [];

View File

@ -22,7 +22,9 @@ namespace Plugin\PollPlugin;
use App\Core\Event; use App\Core\Event;
use App\Core\Module; use App\Core\Module;
use App\Core\Router\RouteLoader;
use Plugin\PollPlugin\Entity\Poll; 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}'; 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<' . ID_FMT . '>}' , [Controller\ShowPoll::class, 'showpoll']); //doesnt work
$r->connect('showpoll', 'main/poll/{id<\\d*>}',[Controller\ShowPoll::class, 'showpoll']); $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('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; return Event::next;
} }

View File

@ -106,7 +106,9 @@ class Poll extends Entity
// }}} Autocode // }}} Autocode
/** /**
* The One True Thingy that must be defined and declared. * Entity schema definition
*
* @return array schema definition
*/ */
public static function schemaDef(): array 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 public static function getFromId(int $id): ?self
{ {
return DB::find('poll', ['id' => $id]); 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); $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 public function getOptionsArr(): array
{ {
return explode("\n", $this->options); return explode("\n", $this->options);
@ -163,18 +186,27 @@ class Poll extends Entity
return true; 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 public function countResponses(): array
{ {
$responses = []; $responses = [];
$options = $this->getOptionsArr(); $options = $this->getOptionsArr();
for ($i = 1; $i <= count($options); ++$i) { for ($i = 0; $i < count($options); ++$i) {
$responses[$options[$i - 1]] = $count = DB::dql('select count(pr) from App\Entity\Poll p, App\Entity\PollResponse pr $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', 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; return $responses;
} }

View File

@ -105,7 +105,9 @@ class PollResponse extends Entity
// }}} Autocode // }}} Autocode
/** /**
* The One True Thingy that must be defined and declared. * Entity schema definition
*
* @return array schema definition
*/ */
public static function schemaDef() 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 public static function exits(int $pollId, int $gsactorId): bool
{ {
$res = DB::dql('select pr from App\Entity\PollResponse pr $res = DB::dql('select pr from App\Entity\PollResponse pr