diff --git a/src/Controller/DefaultController.php b/src/Controller/DefaultController.php index be89c64..6b5189b 100644 --- a/src/Controller/DefaultController.php +++ b/src/Controller/DefaultController.php @@ -1,649 +1,649 @@ json( [ - 'message' => 'here are your polls', - 'poll' => new Poll(), - ] ); - } - - /** - * @Get( - * path = "/polls", - * name = "get_all_polls" - * ) - */ - public function getAllPollsAction() { - $repository = $this->getDoctrine()->getRepository( Poll::class ); - $data = $repository->findall(); + class DefaultController extends AbstractController { - return $this->json( [ - 'message' => 'here are your polls', - 'poll' => $data, - ], - 200 ); - } + /** + * @Get( + * path = "/my-polls", + * name = "get_my_polls", + * requirements = {"access_token"="\w+"} + * ) + */ + public function showMyPollsAction() { + return $this->json( [ + 'message' => 'here are your polls', + 'poll' => new Poll(), + ] ); + } - /** - * @Get( - * path = "/send-polls-to-user/{email}", - * name = "send_user_polls" - * ) - * @param $email - * @param \Swift_Mailer $mailer - * - * @return JsonResponse - */ - public function sendPollsToUser( $email, \Swift_Mailer $mailer ) { - $repository = $this->getDoctrine()->getRepository( Owner::class ); - $founduser = $repository->findOneBy( [ 'email' => $email ] ); + /** + * @Get( + * path = "/polls", + * name = "get_all_polls" + * ) + */ + public function getAllPollsAction() { + $repository = $this->getDoctrine()->getRepository( Poll::class ); + $data = $repository->findall(); - if ( $founduser ) { - $polls = $founduser->getPolls(); - $templateVars = [ - 'owner' => $founduser, - 'polls' => $polls, - ]; - $message = ( new Swift_Message( 'Framadate - mes sondages' ) ) - ->setFrom( 'ne-pas-repondre@framadate-api.cipherbliss.com' ) - ->setTo( $founduser->getEmail() ) - ->setBody( - $this->renderView( - // templates/hello/email.txt.twig - 'emails/owner-list.html.twig', - $templateVars - ) - ); - $mailer->send( $message ); + return $this->json( [ + 'message' => 'here are your polls', + 'poll' => $data, + ], + 200 ); + } - return $this->render( 'emails/owner-list.html.twig', $templateVars ); + /** + * @Get( + * path = "/send-polls-to-user/{email}", + * name = "send_user_polls" + * ) + * @param $email + * @param \Swift_Mailer $mailer + * + * @return JsonResponse + */ + public function sendPollsToUser( $email, \Swift_Mailer $mailer ) { + $repository = $this->getDoctrine()->getRepository( Owner::class ); + $founduser = $repository->findOneBy( [ 'email' => $email ] ); + + if ( $founduser ) { + $polls = $founduser->getPolls(); + $templateVars = [ + 'owner' => $founduser, + 'polls' => $polls, + ]; + + $message = ( new Swift_Message( 'Framadate - mes sondages' ) ) + ->setFrom( 'ne-pas-repondre@framadate-api.cipherbliss.com' ) + ->setTo( $founduser->getEmail() ) + ->setBody( + $this->renderView( + // templates/hello/email.txt.twig + 'emails/owner-list.html.twig', + $templateVars + ) + ); + $mailer->send( $message ); + + return $this->render( 'emails/owner-list.html.twig', $templateVars ); // return $this->json( [ // 'message' => 'here are your polls, ' . $email, // 'data' => 'email was sent with a list of ' . count( $polls ) . ' polls', // ], // 200 ); - } else { - return $this->json( [ - 'message' => 'no user found for email ' . $email, - 'data' => '', - ], - 400 ); - } - // find user by email - // send email - // user not found case - - - } - - /** - * @Post( - * path = "/poll", - * name = "new_poll", - * requirements = {"creator"="\w+"} - * ) - * @param Request $request - * - * @return JsonResponse - */ - public function newPollAction( Request $request ) { - - $data = $request->getContent(); - - $serializer = SerializerBuilder::create()->build(); - $newpoll = $serializer->deserialize( $data, 'App\Entity\Poll', 'json' ); - $newpoll - ->setAdminKey( $newpoll->generateAdminKey() ) - ->setCreationDate( new DateTime() ) - ->setModificationPolicy( 'nobody' ); - $timeStamp = time() + ( 3600 * 24 * 90 ); // 90 days by default - $newpoll->setExpiracyDate( ( new DateTime() )->setTimestamp( $timeStamp ), - new DateTimeZone( 'Europe/Paris' ) ); - $data = json_decode( $data, true ); - $em = $this->getDoctrine()->getRepository( Owner::class ); - $foundOwner = $em->findOneBy( [ 'email' => $data[ 'owner' ][ 'email' ] ] ); - - - $userWasFound = false; - if ( ! $foundOwner ) { - //create a new owner - $owner = new Owner(); - - $owner->setPseudo( $data[ 'owner' ][ 'pseudo' ] ); - $owner->setEmail( $data[ 'owner' ][ 'email' ] ); - $foundOwner = $owner; - } else { - $userWasFound = true; - } - // link the owner and the poll - $newpoll->setOwner( $foundOwner ); - $foundOwner->addPoll( $newpoll ); - - - $em = $this->getDoctrine()->getManager(); - $em->persist( $newpoll ); - $em->persist( $foundOwner ); - - // emails - $newpoll->setMailOnComment( true ); - $newpoll->setMailOnVote( true ); - $newpoll->setHideResults( false ); - // possible answers - $newpoll->setAllowedAnswers( [ 'yes' ] ); - if ( $data[ 'voteChoices' ] ) { - switch ( $data[ 'voteChoices' ] ) { - case "only_yes": - default: - - break; - } - } - // setup the password, converting the raw with md5 hash - if ( $data[ 'password' ] ) { - $newpoll->setPassword( $data[ 'password' ] ); - } - // manage choices - // text kind of answers, dates are below - if ( $data[ 'pollType' ] == 'classic' ) { - $choices = $data[ 'dateList' ]; - foreach ( $choices as $c ) { - $newChoice = new Choice(); - $newChoice - ->setPoll( $newpoll ) -// ->setUrl( $c[ 'url' ] ) - ->setName( $c[ 'literal' ] ); - $em->persist( $newChoice ); - // TODO add also choices for each time range in a day - } - } elseif ( $data[ 'pollType' ] == 'dates' ) { - if ( $data[ 'allowSeveralHours' ] == true ) { - // different hours spans - $choices = $data[ 'dateList' ]; } else { + return $this->json( [ + 'message' => 'no user found for email ' . $email, + 'data' => '', + ], + 400 ); + } + // find user by email + // send email + // user not found case + + + } + + /** + * @Post( + * path = "/poll", + * name = "new_poll", + * requirements = {"creator"="\w+"} + * ) + * @param Request $request + * + * @return JsonResponse + */ + public function newPollAction( Request $request ) { + + $data = $request->getContent(); + + $serializer = SerializerBuilder::create()->build(); + $newpoll = $serializer->deserialize( $data, 'App\Entity\Poll', 'json' ); + $newpoll + ->setAdminKey( $newpoll->generateAdminKey() ) + ->setCreationDate( new DateTime() ) + ->setModificationPolicy( 'nobody' ); + $timeStamp = time() + ( 3600 * 24 * 90 ); // 90 days by default + $newpoll->setExpiracyDate( ( new DateTime() )->setTimestamp( $timeStamp ), + new DateTimeZone( 'Europe/Paris' ) ); + $data = json_decode( $data, true ); + $em = $this->getDoctrine()->getRepository( Owner::class ); + $foundOwner = $em->findOneBy( [ 'email' => $data[ 'owner' ][ 'email' ] ] ); + + + $userWasFound = false; + if ( ! $foundOwner ) { + //create a new owner + $owner = new Owner(); + + $owner->setPseudo( $data[ 'owner' ][ 'pseudo' ] ); + $owner->setEmail( $data[ 'owner' ][ 'email' ] ); + $foundOwner = $owner; + } else { + $userWasFound = true; + } + // link the owner and the poll + $newpoll->setOwner( $foundOwner ); + $foundOwner->addPoll( $newpoll ); + + + $em = $this->getDoctrine()->getManager(); + $em->persist( $newpoll ); + $em->persist( $foundOwner ); + + // emails + $newpoll->setMailOnComment( true ); + $newpoll->setMailOnVote( true ); + $newpoll->setHideResults( false ); + // possible answers + $newpoll->setAllowedAnswers( [ 'yes' ] ); + if ( $data[ 'voteChoices' ] ) { + switch ( $data[ 'voteChoices' ] ) { + case "only_yes": + default: + + break; + } + } + // setup the password, converting the raw with md5 hash + if ( $data[ 'password' ] ) { + $newpoll->setPassword( $data[ 'password' ] ); + } + // manage choices + // text kind of answers, dates are below + if ( $data[ 'pollType' ] == 'classic' ) { + $choices = $data[ 'dateList' ]; + foreach ( $choices as $c ) { + $newChoice = new Choice(); + $newChoice + ->setPoll( $newpoll ) +// ->setUrl( $c[ 'url' ] ) + ->setName( $c[ 'literal' ] ); + $em->persist( $newChoice ); + // TODO add also choices for each time range in a day + } + } elseif ( $data[ 'pollType' ] == 'dates' ) { + if ( $data[ 'allowSeveralHours' ] == true ) { + // different hours spans + $choices = $data[ 'dateList' ]; + } else { // all days have the same hour spans + } + + } + $em->persist( $newpoll ); + $em->flush(); + $precision = ''; + if ( $userWasFound ) { + $precision = 'from an existing user : ' . $foundOwner->getEmail(); + } + + return $this->json( [ + 'message' => 'you created a poll ' . $precision, + 'poll' => $newpoll, + 'password_protected' => is_string( $newpoll->getPassword() ), + 'admin_key' => $newpoll->getAdminKey(), + 'owner_modifier_token' => $foundOwner->getModifierToken(), + + ], + 201 ); } - $em->persist( $newpoll ); - $em->flush(); - $precision = ''; - if ( $userWasFound ) { - $precision = 'from an existing user : ' . $foundOwner->getEmail(); - } - - return $this->json( [ - 'message' => 'you created a poll ' . $precision, - 'poll' => $newpoll, - 'password_protected' => is_string( $newpoll->getPassword() ), - 'admin_key' => $newpoll->getAdminKey(), - 'owner_modifier_token' => $foundOwner->getModifierToken(), - - ], - 201 ); - - } - - /** - * @Get( - * path = "/poll/{id}/comments", - * name = "get_poll_comment", - * requirements = {"poll_id"="\d+"} - * ) - */ - public - function getPollCommentsAction( - Poll $poll - ) { - return $this->json( [ - 'message' => 'here are your comments of the poll', - 'data' => $poll->getComments(), - ], - 200 ); - } - - /** - * @Get( - * path = "/poll/{id}", - * name = "get_poll", - * requirements = {"poll_id"="\d+"} - * ) - */ - public - function getPollConfig( - Poll $poll, - Request $request - ) { - $pass = $poll->getPassword(); - $data = $request->getContent(); - $data = json_decode( $data, true ); - - $comments = []; - $stacks = []; - $choices = []; - foreach ( $poll->getComments() as $c ) { - $comments[] = $c->display(); - } - foreach ( $poll->getStacksOfVotes() as $c ) { - $stacks[] = $c->display(); - } - foreach ( $poll->getChoices() as $c ) { - $choices[] = $c->display(); - } - $returnedPoll = [ - 'message' => 'your poll config', - 'poll' => $poll, - 'stacks_count' => count( $poll->getStacksOfVotes() ), - 'stacks' => $stacks, - 'choices_count' => count( $poll->getChoices() ), - 'choices' => $choices, - 'comments' => $comments, - 'comments_count' => count( $comments ), - ]; /** - * password protected content + * @Get( + * path = "/poll/{id}/comments", + * name = "get_poll_comment", + * requirements = {"poll_id"="\d+"} + * ) */ - if ( $pass ) { - - if ( $pass == md5( $data[ 'password_input' ] ) ) { - return $this->json( - $returnedPoll, + public + function getPollCommentsAction( + Poll $poll + ) { + return $this->json( [ + 'message' => 'here are your comments of the poll', + 'data' => $poll->getComments(), + ], 200 ); + } + + /** + * @Get( + * path = "/poll/{id}", + * name = "get_poll", + * requirements = {"poll_id"="\d+"} + * ) + */ + public + function getPollConfig( + Poll $poll, + Request $request + ) { + $pass = $poll->getPassword(); + $data = $request->getContent(); + $data = json_decode( $data, true ); + + $comments = []; + $stacks = []; + $choices = []; + foreach ( $poll->getComments() as $c ) { + $comments[] = $c->display(); + } + foreach ( $poll->getStacksOfVotes() as $c ) { + $stacks[] = $c->display(); + } + foreach ( $poll->getChoices() as $c ) { + $choices[] = $c->display(); + } + $returnedPoll = [ + 'message' => 'your poll config', + 'poll' => $poll, + 'stacks_count' => count( $poll->getStacksOfVotes() ), + 'stacks' => $stacks, + 'choices_count' => $poll->computeAnswers(), + 'choices' => $choices, + 'comments' => $comments, + 'comments_count' => count( $comments ), + ]; + /** + * password protected content + */ + if ( $pass ) { + + if ( $pass == md5( $data[ 'password_input' ] ) ) { + return $this->json( + $returnedPoll, + 200 ); + } else { + return $this->json( [ + 'message' => 'your password ' . $data[ 'password_input' ] . ' is wrong, and you should feel bad', + 'data' => null, + ], + 403 ); + } + } else { + return $this->json( + $returnedPoll + , + 200 ); + } + + } + + /** + * Delete all expired polls and their children + * @Get( + * path = "/clean-polls", + * name = "clean_expired_polls", + * ) + */ + public + function cleanExpiredPolls() { + $em = $this->getDoctrine()->getManager(); + $emPoll = $this->getDoctrine()->getRepository( Poll::class ); + + $queryFind = $em->createQuery( + 'SELECT p + FROM App\Entity\Poll p + WHERE p.expiracyDate < CURRENT_DATE()' + ); + $queryDelete = $em->createQuery( + 'DELETE + FROM App\Entity\Poll p + WHERE p.expiracyDate < CURRENT_DATE()' + ); + + $foundPolls = $queryFind->getResult(); + + $em->flush(); + + return $this->json( [ + 'message' => 'clean routine has been done, here are the numbers of polls deleted: ' . count( $foundPolls ), + 'data' => [ + 'count' => count( $foundPolls ), + ], + ], + 200 ); + } + + /** + * @Put( + * path = "/poll/{id}", + * name = "update_poll", + * requirements = {"content"="\w+", "poll_id"="\d+"} + * ) + */ + public + function updatePollConfig( + Poll $poll, + Request $request + ) { + + // TODO check validity of request + // update only if we have the admin key + $em = $this->getDoctrine()->getManager(); + $em->persist( $poll ); + $em->flush(); + + return $this->json( [ + 'message' => 'you updated the poll ' . $poll->getTitle(), + ] ); + } + + /** + * add a comment on a poll + * @Post( + * path = "/poll/{id}/comment", + * name = "new_comment", + * requirements = {"content"="\w+", "poll_id"="\d+"} + * ) + */ + public + function newCommentAction( + Poll $poll, + Request $request + ) { + if ( ! $poll ) { + return $this->json( [ 'message' => 'poll not found' ], 404 ); + } + $data = $request->getContent(); + + $serializer = SerializerBuilder::create()->build(); + $comment = $serializer->deserialize( $data, 'App\Entity\Comment', 'json' ); + + $em = $this->getDoctrine()->getRepository( Owner::class ); + + $data = json_decode( $data, true ); + + $foundOwner = $em->findOneByEmail( $data[ 'email' ] ); + // manage existing or new Owner + if ( ! $foundOwner ) { + $foundOwner = new Owner(); + $foundOwner->setPseudo( $data[ 'owner' ][ 'email' ] ) + ->setEmail( $data[ 'owner' ][ 'email' ] ) + ->setModifierToken( uniqid() ); + } + // anti flood + $seconds_limit_lastpost = 5; + $emComment = $this->getDoctrine()->getRepository( Comment::class ); + $lastCommentOfOwner = $emComment->findBy( [ 'owner' => $foundOwner ], [ 'id' => 'desc' ] ); + + // TODO anti flood by session / IP + + if ( $lastCommentOfOwner ) { + + + // check time of last comment + $now = new \DateTime(); + $now = $now->format( 'Y-m-d H:i:s' ); + $date_first = strtotime( $lastCommentOfOwner[ 0 ]->getCreatedAt()->format( 'Y-m-d H:i:s' ) ); + $date_second = strtotime( $now ); + + if ( ( $date_second - $date_first ) < $seconds_limit_lastpost ) { + return $this->json( [ + 'message' => 'anti flood déclenché', + 'details' => 'votre deriner commentaire a été envoyé il y a moins de ' . $seconds_limit_lastpost . ' secondes', + ], + 403 ); + } + + // check similar text content + if ( $lastCommentOfOwner[ 0 ]->getText() == $comment->getText() ) { + return $this->json( [ + 'message' => 'anti flood déclenché', + 'details' => 'votre deriner commentaire a exactement le même contenu que celui ci, il n\'a donc pas été créé', + ], + 403 ); + } + } + $comment->setOwner( $foundOwner ) + ->setCreatedAt( new \DateTime() ) + ->setPoll( $poll ); + $foundOwner->addComment( $comment ); + + $em = $this->getDoctrine()->getManager(); + $em->persist( $foundOwner ); + $em->persist( $comment ); + $em->flush(); + + return $this->json( [ + 'message' => 'you created a comment', + 'data' => [ + 'your_comment' => $comment->display(), + ], + ], + 201 ); + } + + /** + * add a vote on a poll + * @Post( + * path = "/poll/{id}/vote", + * name = "new_vote_stack", + * requirements = {"content"="\w+", "poll_id"="\d+"} + * ) + */ + public + function newVoteStackAction( + Poll $poll, + Request $request + ) { + if ( ! $poll ) { + return $this->json( [ 'message' => 'poll not found' ], 404 ); + } + + $em = $this->getDoctrine()->getManager(); + $data = $request->getContent(); + $data = json_decode( $data, true ); + + + $emOwner = $this->getDoctrine()->getRepository( Owner::class ); + $emChoice = $this->getDoctrine()->getRepository( Choice::class ); + $existingOwner = false; + $foundOwner = $emOwner->findOneByEmail( trim( $data[ 'email' ] ) ); + // manage existing or new Owner + if ( ! $foundOwner ) { + $foundOwner = new Owner(); + $foundOwner + ->setEmail( $data[ 'email' ] ) + ->setPseudo( $data[ 'pseudo' ] ); + } else { + $existingOwner = true; + } + // TODO anti flood + $foundOwner + ->setModifierToken( $poll->generateAdminKey() ); + $stack = new StackOfVotes(); + $stack + ->setOwner( $foundOwner ) + ->setPseudo( $data[ 'pseudo' ] ) + ->setPoll( $poll ); + foreach ( $data[ 'votes' ] as $voteInfo ) { + + if ( ! isset( $voteInfo[ 'value' ] ) ) { + continue; + } + $allowedValuesToAnswer = [ 'yes', 'maybe', 'no' ]; + + if ( ! in_array( $voteInfo[ 'value' ], $allowedValuesToAnswer ) ) { + return $this->json( [ + 'message' => 'answer ' . $voteInfo[ 'value' ] . ' is not allowed. should be yes, maybe, or no.', + 'vote_stack' => $stack, + ], + 404 ); + } + $vote = new Vote(); + $foundChoice = $emChoice->find( $voteInfo[ 'choice_id' ] ); + if ( ! $foundChoice ) { + return $this->json( [ + 'message' => 'choice ' . $voteInfo[ 'choice_id' ] . ' was not found', + 'vote_stack' => $stack, + ], + 404 ); + } + $vote->setPoll( $poll ) + ->setChoice( $foundChoice ) + ->setValue( $voteInfo[ 'value' ] ); + $vote->setPoll( $poll ); + $stack->addVote( $vote ); + $poll->addVote( $vote ); + $em->persist( $vote ); + $em->persist( $foundChoice ); + } + + // find poll from choices + $poll->addStackOfVote( $stack ); + $em->persist( $stack ); + $em->persist( $poll ); + $em->flush(); + $precision = ''; + if ( $existingOwner ) { + $precision = ' from an existing owner : ' . $foundOwner->getEmail(); + } + + return $this->json( [ + 'message' => 'you created a vote stack' . $precision, + 'poll' => $poll, + 'vote_stack' => $stack->display(), + 'vote_count' => count( $poll->getStacksOfVotes() ), + 'owner_modifier_token' => $foundOwner->getModifierToken(), + 'admin_key' => $poll->getAdminKey(), + 'json_you_sent' => $data, + ], + 201 ); + } + + + /** + * @Delete( + * path = "/poll/{id}", + * name = "poll_delete", + * requirements = {"accessToken"="\w+", "poll_id"="\d+"} + * ) + * @param Poll $poll + * @param $accessToken + * + * @return JsonResponse + */ + public + function deletePollAction( + Poll $poll, + $accessToken + ) { + + if ( $accessToken == $poll->getAdminKey() ) { + $em = $this->getDoctrine()->getManager(); + $em->remove( $poll ); + $em->flush(); + + return $this->json( [ + 'message' => 'boom! le sondage et ses objets assocités a été supprimé', + ] ); } else { return $this->json( [ - 'message' => 'your password ' . $data[ 'password_input' ] . ' is wrong, and you should feel bad', - 'data' => null, - ], - 403 ); + 'message' => 'le token d\'autorisation est invalide, vous ne pouvez pas modifier ce sondage', + ] ); } - } else { - return $this->json( - $returnedPoll - , - 200 ); + } - } + /** + * Erase all comments of a poll + * @Delete( + * path = "/poll/{id}/comments", + * name = "poll_comments_delete", + * requirements = {"accessToken"="\w+", "poll_id"="\d+"} + * ) + * + * @param Poll $poll + * @param $accessToken + * + * @return JsonResponse + */ + public + function deletePollCommentsAction( + Poll $poll, + $accessToken + ) { + if ( $accessToken == $poll->getAdminKey() ) { + $em = $this->getDoctrine()->getManager(); + $length = count( $poll->getComments() ); + $em->remove( $poll->getComments() ); + $em->flush(); - /** - * Delete all expired polls and their children - * @Get( - * path = "/clean-polls", - * name = "clean_expired_polls", - * ) - */ - public - function cleanExpiredPolls() { - $em = $this->getDoctrine()->getManager(); - $emPoll = $this->getDoctrine()->getRepository( Poll::class ); - - $queryFind = $em->createQuery( - 'SELECT p - FROM App\Entity\Poll p - WHERE p.expiracyDate < CURRENT_DATE()' - ); - $queryDelete = $em->createQuery( - 'DELETE - FROM App\Entity\Poll p - WHERE p.expiracyDate < CURRENT_DATE()' - ); - - $foundPolls = $queryFind->getResult(); - - $em->flush(); - - return $this->json( [ - 'message' => 'clean routine has been done, here are the numbers of polls deleted: ' . count( $foundPolls ), - 'data' => [ - 'count' => count( $foundPolls ), - ], - ], - 200 ); - } - - /** - * @Put( - * path = "/poll/{id}", - * name = "update_poll", - * requirements = {"content"="\w+", "poll_id"="\d+"} - * ) - */ - public - function updatePollConfig( - Poll $poll, - Request $request - ) { - - // TODO check validity of request - // update only if we have the admin key - $em = $this->getDoctrine()->getManager(); - $em->persist( $poll ); - $em->flush(); - - return $this->json( [ - 'message' => 'you updated the poll ' . $poll->getTitle(), - ] ); - } - - /** - * add a comment on a poll - * @Post( - * path = "/poll/{id}/comment", - * name = "new_comment", - * requirements = {"content"="\w+", "poll_id"="\d+"} - * ) - */ - public - function newCommentAction( - Poll $poll, - Request $request - ) { - if ( ! $poll ) { - return $this->json( [ 'message' => 'poll not found' ], 404 ); - } - $data = $request->getContent(); - - $serializer = SerializerBuilder::create()->build(); - $comment = $serializer->deserialize( $data, 'App\Entity\Comment', 'json' ); - - $em = $this->getDoctrine()->getRepository( Owner::class ); - - $data = json_decode( $data, true ); - - $foundOwner = $em->findOneByEmail( $data[ 'email' ] ); - // manage existing or new Owner - if ( ! $foundOwner ) { - $foundOwner = new Owner(); - $foundOwner->setPseudo( $data[ 'owner' ][ 'email' ] ) - ->setEmail( $data[ 'owner' ][ 'email' ] ) - ->setModifierToken( uniqid() ); - } - // anti flood - $seconds_limit_lastpost = 5; - $emComment = $this->getDoctrine()->getRepository( Comment::class ); - $lastCommentOfOwner = $emComment->findBy( [ 'owner' => $foundOwner ], [ 'id' => 'desc' ] ); - - // TODO anti flood by session / IP - - if ( $lastCommentOfOwner ) { - - - // check time of last comment - $now = new \DateTime(); - $now = $now->format( 'Y-m-d H:i:s' ); - $date_first = strtotime( $lastCommentOfOwner[ 0 ]->getCreatedAt()->format( 'Y-m-d H:i:s' ) ); - $date_second = strtotime( $now ); - - if ( ( $date_second - $date_first ) < $seconds_limit_lastpost ) { return $this->json( [ - 'message' => 'anti flood déclenché', - 'details' => 'votre deriner commentaire a été envoyé il y a moins de ' . $seconds_limit_lastpost . ' secondes', - ], - 403 ); - } - - // check similar text content - if ( $lastCommentOfOwner[ 0 ]->getText() == $comment->getText() ) { + 'message' => 'boom! les ' . $length . ' commentaires du sondage ont été supprimés', + ] ); + } else { return $this->json( [ - 'message' => 'anti flood déclenché', - 'details' => 'votre deriner commentaire a exactement le même contenu que celui ci, il n\'a donc pas été créé', - ], - 403 ); + 'message' => 'le token d\'autorisation est invalide, vous ne pouvez pas modifier ce sondage', + ] ); } } - $comment->setOwner( $foundOwner ) - ->setCreatedAt( new \DateTime() ) - ->setPoll( $poll ); - $foundOwner->addComment( $comment ); - $em = $this->getDoctrine()->getManager(); - $em->persist( $foundOwner ); - $em->persist( $comment ); - $em->flush(); + /** + * @Delete( + * path = "/poll/{id}/votes/{accessToken}", + * name = "poll_votes_delete", + * requirements = {"accessToken"="\w+", "poll_id"="\d+"} + * ) + * @return JsonResponse + */ + public + function deletePollVotesAction( + Poll $poll, + $accessToken + ) { + if ( $accessToken == $poll->getAdminKey() ) { + $em = $this->getDoctrine()->getManager(); + $length = count( $poll->getVotes() ); + $em->remove( $poll->getVotes() ); + $em->flush(); - return $this->json( [ - 'message' => 'you created a comment', - 'data' => [ - 'your_comment' => $comment->display(), - ], - ], - 201 ); - } - - /** - * add a vote on a poll - * @Post( - * path = "/poll/{id}/vote", - * name = "new_vote_stack", - * requirements = {"content"="\w+", "poll_id"="\d+"} - * ) - */ - public - function newVoteStackAction( - Poll $poll, - Request $request - ) { - if ( ! $poll ) { - return $this->json( [ 'message' => 'poll not found' ], 404 ); - } - - $em = $this->getDoctrine()->getManager(); - $data = $request->getContent(); - $data = json_decode( $data, true ); - - - $emOwner = $this->getDoctrine()->getRepository( Owner::class ); - $emChoice = $this->getDoctrine()->getRepository( Choice::class ); - $existingOwner = false; - $foundOwner = $emOwner->findOneByEmail( trim( $data[ 'email' ] ) ); - // manage existing or new Owner - if ( ! $foundOwner ) { - $foundOwner = new Owner(); - $foundOwner - ->setEmail( $data[ 'email' ] ) - ->setPseudo( $data[ 'pseudo' ] ); - } else { - $existingOwner = true; - } - // TODO anti flood - $foundOwner - ->setModifierToken( $poll->generateAdminKey() ); - $stack = new StackOfVotes(); - $stack - ->setOwner( $foundOwner ) - ->setPseudo( $data[ 'pseudo' ] ) - ->setPoll( $poll ); - foreach ( $data[ 'votes' ] as $voteInfo ) { - - if ( ! isset( $voteInfo[ 'value' ] ) ) { - continue; - } - $allowedValuesToAnswer = [ 'yes', 'maybe', 'no' ]; - - if ( ! in_array( $voteInfo[ 'value' ], $allowedValuesToAnswer ) ) { return $this->json( [ - 'message' => 'answer ' . $voteInfo[ 'value' ] . ' is not allowed. should be yes, maybe, or no.', - 'vote_stack' => $stack, - ], - 404 ); - } - $vote = new Vote(); - $foundChoice = $emChoice->find( $voteInfo[ 'choice_id' ] ); - if ( ! $foundChoice ) { + 'message' => 'boom! les ' . $length . ' votes du sondage ont été supprimés', + ] ); + } else { return $this->json( [ - 'message' => 'choice ' . $voteInfo[ 'choice_id' ] . ' was not found', - 'vote_stack' => $stack, - ], - 404 ); + 'message' => 'le token d\'autorisation est invalide, vous ne pouvez pas modifier ce sondage', + ] ); } - $vote->setPoll( $poll ) - ->setChoice( $foundChoice ) - ->setValue( $voteInfo[ 'value' ] ); - $vote->setPoll( $poll ); - $stack->addVote( $vote ); - $poll->addVote( $vote ); - $em->persist( $vote ); - $em->persist( $foundChoice ); - } - // find poll from choices - $poll->addStackOfVote( $stack ); - $em->persist( $stack ); - $em->persist( $poll ); - $em->flush(); - $precision = ''; - if ( $existingOwner ) { - $precision = ' from an existing owner : ' . $foundOwner->getEmail(); - } - - return $this->json( [ - 'message' => 'you created a vote stack' . $precision, - 'poll' => $poll, - 'vote_stack' => $stack->display(), - 'vote_count' => count( $poll->getStacksOfVotes() ), - 'owner_modifier_token' => $foundOwner->getModifierToken(), - 'admin_key' => $poll->getAdminKey(), - 'json_you_sent' => $data, - ], - 201 ); - } - - - /** - * @Delete( - * path = "/poll/{id}", - * name = "poll_delete", - * requirements = {"accessToken"="\w+", "poll_id"="\d+"} - * ) - * @param Poll $poll - * @param $accessToken - * - * @return JsonResponse - */ - public - function deletePollAction( - Poll $poll, - $accessToken - ) { - - if ( $accessToken == $poll->getAdminKey() ) { - $em = $this->getDoctrine()->getManager(); - $em->remove( $poll ); - $em->flush(); - - return $this->json( [ - 'message' => 'boom! le sondage et ses objets assocités a été supprimé', - ] ); - } else { - return $this->json( [ - 'message' => 'le token d\'autorisation est invalide, vous ne pouvez pas modifier ce sondage', - ] ); } } - - /** - * Erase all comments of a poll - * @Delete( - * path = "/poll/{id}/comments", - * name = "poll_comments_delete", - * requirements = {"accessToken"="\w+", "poll_id"="\d+"} - * ) - * - * @param Poll $poll - * @param $accessToken - * - * @return JsonResponse - */ - public - function deletePollCommentsAction( - Poll $poll, - $accessToken - ) { - if ( $accessToken == $poll->getAdminKey() ) { - $em = $this->getDoctrine()->getManager(); - $length = count( $poll->getComments() ); - $em->remove( $poll->getComments() ); - $em->flush(); - - return $this->json( [ - 'message' => 'boom! les ' . $length . ' commentaires du sondage ont été supprimés', - ] ); - } else { - return $this->json( [ - 'message' => 'le token d\'autorisation est invalide, vous ne pouvez pas modifier ce sondage', - ] ); - } - } - - /** - * @Delete( - * path = "/poll/{id}/votes/{accessToken}", - * name = "poll_votes_delete", - * requirements = {"accessToken"="\w+", "poll_id"="\d+"} - * ) - * @return JsonResponse - */ - public - function deletePollVotesAction( - Poll $poll, - $accessToken - ) { - if ( $accessToken == $poll->getAdminKey() ) { - $em = $this->getDoctrine()->getManager(); - $length = count( $poll->getVotes() ); - $em->remove( $poll->getVotes() ); - $em->flush(); - - return $this->json( [ - 'message' => 'boom! les ' . $length . ' votes du sondage ont été supprimés', - ] ); - } else { - return $this->json( [ - 'message' => 'le token d\'autorisation est invalide, vous ne pouvez pas modifier ce sondage', - ] ); - } - - } - -} diff --git a/src/Entity/Choice.php b/src/Entity/Choice.php index 4b03863..ce2a0fc 100644 --- a/src/Entity/Choice.php +++ b/src/Entity/Choice.php @@ -1,144 +1,145 @@ poll = new ArrayCollection(); - $this->votes = new ArrayCollection(); - $this->setDateTime( new DateTime() ); - if ( $optionalName ) { - $this->setName( $optionalName ); - } - } + /** + * @ORM\Column(type="datetime", nullable=true) + * @Serializer\Type("datetime") + */ + public $dateTime; + /** + * @ORM\OneToMany(targetEntity="App\Entity\Vote", mappedBy="choice", cascade={"persist"}) + * @Serializer\Type("App\Entity\Vote") + */ + public $votes; + /** + * @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="choices", cascade={"persist"}) + * @Serializer\Type("App\Entity\Poll") + */ + private $poll; - public function display() { - return [ - 'id' => $this->getId(), - 'date' => $this->getDateTime(), - 'text' => $this->getName(), - 'url' => $this->getUrl(), - ]; - } - - public function getId(): ?int { - return $this->id; - } - - public function getDateTime(): ?DateTimeInterface { - return $this->dateTime; - } - - public function setDateTime( ?DateTimeInterface $dateTime ): self { - $this->dateTime = $dateTime; - - return $this; - } - - public function getName(): ?string { - return $this->name; - } - - public function setName( ?string $name ): self { - $this->name = $name; - - return $this; - } - - public function getPoll(): ?Poll { - return $this->poll; - } - - public function setPoll( ?Poll $poll ): self { - $this->poll = $poll; - - return $this; - } - - /** - * @return Collection|Vote[] - */ - public function getVotes(): Collection { - return $this->votes; - } - - public function addVote( Vote $vote ): self { - if ( ! $this->votes->contains( $vote ) ) { - $this->votes[] = $vote; - $vote->setChoice( $this ); - } - - return $this; - } - - public function removeVote( Vote $vote ): self { - if ( $this->votes->contains( $vote ) ) { - $this->votes->removeElement( $vote ); - // set the owning side to null (unless already changed) - if ( $vote->getChoice() === $this ) { - $vote->setChoice( null ); + public function __construct( $optionalName = null ) { + $this->poll = new ArrayCollection(); + $this->votes = new ArrayCollection(); + $this->setDateTime( new DateTime() ); + if ( $optionalName ) { + $this->setName( $optionalName ); } } - return $this; - } - public function getUrl(): ?string { - return $this->url; - } + public function display() { + return [ + 'id' => $this->getId(), + 'date' => $this->getDateTime(), + 'text' => $this->getName(), + 'url' => $this->getUrl(), + ]; + } - public function setUrl( ?string $url ): self { - $this->url = $url; + public function getId(): ?int { + return $this->id; + } - return $this; + public function getDateTime(): ?DateTimeInterface { + return $this->dateTime; + } + + public function setDateTime( ?DateTimeInterface $dateTime ): self { + $this->dateTime = $dateTime; + + return $this; + } + + public function getName(): ?string { + return $this->name; + } + + public function setName( ?string $name ): self { + $this->name = $name; + + return $this; + } + + public function getPoll(): ?Poll { + return $this->poll; + } + + public function setPoll( ?Poll $poll ): self { + $this->poll = $poll; + + return $this; + } + + /** + * @return Collection|Vote[] + */ + public function getVotes(): Collection { + return $this->votes; + } + + public function addVote( Vote $vote ): self { + if ( ! $this->votes->contains( $vote ) ) { + $this->votes[] = $vote; + $vote->setChoice( $this ); + } + + return $this; + } + + public function removeVote( Vote $vote ): self { + if ( $this->votes->contains( $vote ) ) { + $this->votes->removeElement( $vote ); + // set the owning side to null (unless already changed) + if ( $vote->getChoice() === $this ) { + $vote->setChoice( null ); + } + } + + return $this; + } + + public function getUrl(): ?string { + return $this->url; + } + + public function setUrl( ?string $url ): self { + $this->url = $url; + + return $this; + } } -} diff --git a/src/Entity/Poll.php b/src/Entity/Poll.php index c1d1f8c..38e847d 100644 --- a/src/Entity/Poll.php +++ b/src/Entity/Poll.php @@ -1,546 +1,579 @@ votes = new ArrayCollection(); - $this->stacksOfVotes = new ArrayCollection(); - $this->choices = new ArrayCollection(); - $this->comments = new ArrayCollection(); - $this->initiate(); - } + /** + * number of days from now for default expiracy date + * @var int + * @Serializer\Expose() + */ + public $defaultExpiracyDaysFromNow = 60; + private $maxChoicesLimit = 25; + public function computeAnswers() { + // counts each number of answer for this choice + $computedArray = []; + $people = []; - private function initiate() { - $this->adminKey = $this->generateAdminKey(); - $this->setCreationDate( new \DateTime() ); - $this->setExpiracyDate( $this->addDaysToDate( - new \DateTime(), - $this->defaultExpiracyDaysFromNow - ) ); - $this->setAllowedAnswers( [ 'yes' ] ); - } - - public function generateAdminKey() { - $rand = random_int( PHP_INT_MIN, PHP_INT_MAX ); - - return str_shuffle( md5( $rand ) . $rand . $this->random_str() ); - } - - /** - * Generate a random string, using a cryptographically secure - * pseudorandom number generator (random_int) - * - * This function uses type hints now (PHP 7+ only), but it was originally - * written for PHP 5 as well. - * - * For PHP 7, random_int is a PHP core function - * For PHP 5.x, depends on https://github.com/paragonie/random_compat - * - * @param int $length How many characters do we want? - * @param string $keyspace A string of all possible characters - * to select from - * - * @return string - */ - public function random_str( - int $length = 64, - string $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' - ): string { - if ( $length < 1 ) { - throw new \RangeException( "Length must be a positive integer" ); - } - $pieces = []; - $max = mb_strlen( $keyspace, '8bit' ) - 1; - for ( $i = 0 ; $i < $length ; ++ $i ) { - $pieces [] = $keyspace[ random_int( 0, $max ) ]; - } - - return implode( '', $pieces ); - } - - public function findChoiceById( int $id ) { - - $choices = $this->getChoices(); - $counter = 0; - // there must be something cleaner than this in Doctrine ArrayCollection - foreach ( $choices as $choice ) { - $counter ++; - if ( $counter > $this->maxChoicesLimit ) { - throw new \ErrorException( "max number of choices reached for this poll" ); - } - if ( $choice && $choice->getId() == $id ) { - return $choice; + foreach ( $this->getStacksOfVotes() as $stack_of_vote ) { + foreach ( $stack_of_vote->getVotes() as $vote ) { + if ( ! isset( $computedArray[ $vote->getChoice()->getId() ] ) ) { + $computedArray[ $vote->getChoice()->getId() ] = [ + 'yes' => 0, + 'maybe' => 0, + 'no' => 0, + ]; + } + $computedArray[ $vote->getChoice()->getId() ][ $vote->getValue() ] ++; + $people[ $stack_of_vote->getOwner()->getPseudo() ] = $vote->getValue(); + } } + return [ + 'counts' => $computedArray, + 'people' => $people, + ]; } - return null; - } - - public function addDaysToDate( \DateTime $date, int $days ) { - $st = strtotime( $date->getTimestamp() . ' + ' . $days . ' days' ); - - return new \DateTime( $st ); - } - - public function getId(): ?int { - return $this->id; - } - - public function getTitle(): ?string { - return $this->title; - } - - public function setTitle( string $title ): self { - $this->title = $title; - - return $this; - } - - public function getCreationDate(): ?DateTimeInterface { - return $this->creationDate; - } - - public function setCreationDate( DateTimeInterface $creationDate ): self { - $this->creationDate = $creationDate; - - return $this; - } - - public function setExpiracyDate( DateTimeInterface $expiracyDate ): self { - $this->expiracyDate = $expiracyDate; - - return $this; - } - - public function getOwner(): ?Owner { - return $this->owner; - } - - public function setOwner( ?Owner $owner ): self { - $this->owner = $owner; - - return $this; - } - - /** - * @return Collection|Vote[] - */ - public function getVotes(): Collection { - return $this->votes; - } - - - public function getAdminKey(): ?string { - return $this->adminKey; - } - - public function setAdminKey( string $adminKey ): self { - $this->adminKey = $adminKey; - - return $this; - } - - public function getDescription(): ?string { - return $this->description; - } - - public function setDescription( string $description ): self { - $this->description = $description; - - return $this; - } - - public function getKind(): ?string { - return $this->kind; - } - - public function setKind( string $kind ): self { - $this->kind = $kind; - - return $this; - } - - public function getCustomUrl(): ?string { - return $this->customUrl; - } - - public function setCustomUrl( string $customUrl ): self { - $this->customUrl = $customUrl; - - return $this; - } - - public function getPassword(): ?string { - return $this->password; - } - - public function setPassword( string $password ): self { - $this->password = md5( $password ); - - return $this; - } - - public function getModificationPolicy(): ?string { - return $this->modificationPolicy; - } - - public function setModificationPolicy( string $modificationPolicy ): self { - $this->modificationPolicy = $modificationPolicy; - - return $this; - } - - public function getMailOnComment(): ?bool { - return $this->mailOnComment; - } - - public function setMailOnComment( bool $mailOnComment ): self { - $this->mailOnComment = $mailOnComment; - - return $this; - } - - public function getMailOnVote(): ?bool { - return $this->mailOnVote; - } - - public function setMailOnVote( bool $mailOnVote ): self { - $this->mailOnVote = $mailOnVote; - - return $this; - } - - public function getHideResults(): ?bool { - return $this->hideResults; - } - - public function setHideResults( bool $hideResults ): self { - $this->hideResults = $hideResults; - - return $this; - } - - public function getShowResultEvenIfPasswords(): ?bool { - return $this->showResultEvenIfPasswords; - } - - public function setShowResultEvenIfPasswords( bool $showResultEvenIfPasswords ): self { - $this->showResultEvenIfPasswords = $showResultEvenIfPasswords; - - return $this; - } - - - /** - * @return Collection|Comment[] - */ - public function getComments(): Collection { - return $this->comments; - } - - public function addComment( Comment $comment ): self { - if ( ! $this->comments->contains( $comment ) ) { - $this->comments[] = $comment; - $comment->setPoll( $this ); + public function display() { + return [ + 'poll' => $this, + 'answers' => $this->computeAnswers(), + ]; } - return $this; - } + public function __construct() { + $this->votes = new ArrayCollection(); + $this->stacksOfVotes = new ArrayCollection(); + $this->choices = new ArrayCollection(); + $this->comments = new ArrayCollection(); + $this->initiate(); + } - public function removeComment( Comment $comment ): self { - if ( $this->comments->contains( $comment ) ) { - $this->comments->removeElement( $comment ); - // set the owning side to null (unless already changed) - if ( $comment->getPoll() === $this ) { - $comment->setPoll( null ); + + private function initiate() { + $this->adminKey = $this->generateAdminKey(); + $this->setCreationDate( new \DateTime() ); + $this->setExpiracyDate( $this->addDaysToDate( + new \DateTime(), + $this->defaultExpiracyDaysFromNow + ) ); + $this->setAllowedAnswers( [ 'yes' ] ); + } + + + public function generateAdminKey() { + $rand = random_int( PHP_INT_MIN, PHP_INT_MAX ); + + return str_shuffle( md5( $rand ) . $rand . $this->random_str() ); + } + + /** + * Generate a random string, using a cryptographically secure + * pseudorandom number generator (random_int) + * + * This function uses type hints now (PHP 7+ only), but it was originally + * written for PHP 5 as well. + * + * For PHP 7, random_int is a PHP core function + * For PHP 5.x, depends on https://github.com/paragonie/random_compat + * + * @param int $length How many characters do we want? + * @param string $keyspace A string of all possible characters + * to select from + * + * @return string + */ + public function random_str( + int $length = 64, + string $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' + ): string { + if ( $length < 1 ) { + throw new \RangeException( "Length must be a positive integer" ); } - } - - return $this; - } - - public function getStacksOfVotes() { - return $this->stacksOfVotes; - } - - public function setStacksOfVotes( ?StackOfVotes $stacksOfVotes ): self { - $this->stacksOfVotes = $stacksOfVotes; - - return $this; - } - - - public function addStackOfVote( StackOfVotes $stackOfVote ): self { - if ( ! $this->stacksOfVotes->contains( $stackOfVote ) ) { - $this->stacksOfVotes[] = $stackOfVote; - $stackOfVote->setPoll( $this ); - } - - return $this; - } - - public function removeStackOfVote( StackOfVotes $stackOfVote ): self { - if ( $this->stacksOfVotes->contains( $stackOfVote ) ) { - $this->stacksOfVotes->removeElement( $stackOfVote ); - // set the owning side to null (unless already changed) - if ( $stackOfVote->getPoll() === $this ) { - $stackOfVote->setPoll( null ); + $pieces = []; + $max = mb_strlen( $keyspace, '8bit' ) - 1; + for ( $i = 0 ; $i < $length ; ++ $i ) { + $pieces [] = $keyspace[ random_int( 0, $max ) ]; } + + return implode( '', $pieces ); } - return $this; - } + public function findChoiceById( int $id ) { - public function getExpiracyDate(): ?\DateTimeInterface { - return $this->expiracyDate; - } + $choices = $this->getChoices(); + $counter = 0; + // there must be something cleaner than this in Doctrine ArrayCollection + foreach ( $choices as $choice ) { + $counter ++; + if ( $counter > $this->maxChoicesLimit ) { + throw new \ErrorException( "max number of choices reached for this poll" ); + } + if ( $choice && $choice->getId() == $id ) { + return $choice; + } - public function addVote( Vote $vote ): self { - if ( ! $this->votes->contains( $vote ) ) { - $this->votes[] = $vote; - $vote->setPoll( $this ); - } - - return $this; - } - - public function removeVote( Vote $vote ): self { - if ( $this->votes->contains( $vote ) ) { - $this->votes->removeElement( $vote ); - // set the owning side to null (unless already changed) - if ( $vote->getPoll() === $this ) { - $vote->setPoll( null ); } + + return null; } - return $this; - } + public function addDaysToDate( \DateTime $date, int $days ) { + $st = strtotime( $date->getTimestamp() . ' + ' . $days . ' days' ); - /** - * @return Collection|Choice[] - */ - public function getChoices(): Collection { - return $this->choices; - } - - public function addTextChoiceArray( Array $choiceTextArray ): self { - foreach ( $choiceTextArray as $text ) { - $newChoice = new Choice(); - $newChoice->setName( $text ); - $this->addChoice( $newChoice ); + return new \DateTime( $st ); } - return $this; - } - - - public function getAllowedAnswers(): ?array { - return $this->allowedAnswers; - } - - public function setAllowedAnswers( array $allowedAnswers ): self { - $this->allowedAnswers = $allowedAnswers; - - return $this; - } - - public function addStacksOfVote( StackOfVotes $stacksOfVote ): self { - if ( ! $this->stacksOfVotes->contains( $stacksOfVote ) ) { - $this->stacksOfVotes[] = $stacksOfVote; - $stacksOfVote->setPoll( $this ); + public function getId(): ?int { + return $this->id; } - return $this; - } + public function getTitle(): ?string { + return $this->title; + } - public function removeStacksOfVote( StackOfVotes $stacksOfVote ): self { - if ( $this->stacksOfVotes->contains( $stacksOfVote ) ) { - $this->stacksOfVotes->removeElement( $stacksOfVote ); - // set the owning side to null (unless already changed) - if ( $stacksOfVote->getPoll() === $this ) { - $stacksOfVote->setPoll( null ); + public function setTitle( string $title ): self { + $this->title = $title; + + return $this; + } + + public function getCreationDate(): ?DateTimeInterface { + return $this->creationDate; + } + + public function setCreationDate( DateTimeInterface $creationDate ): self { + $this->creationDate = $creationDate; + + return $this; + } + + public function setExpiracyDate( DateTimeInterface $expiracyDate ): self { + $this->expiracyDate = $expiracyDate; + + return $this; + } + + public function getOwner(): ?Owner { + return $this->owner; + } + + public function setOwner( ?Owner $owner ): self { + $this->owner = $owner; + + return $this; + } + + /** + * @return Collection|Vote[] + */ + public function getVotes(): Collection { + return $this->votes; + } + + + public function getAdminKey(): ?string { + return $this->adminKey; + } + + public function setAdminKey( string $adminKey ): self { + $this->adminKey = $adminKey; + + return $this; + } + + public function getDescription(): ?string { + return $this->description; + } + + public function setDescription( string $description ): self { + $this->description = $description; + + return $this; + } + + public function getKind(): ?string { + return $this->kind; + } + + public function setKind( string $kind ): self { + $this->kind = $kind; + + return $this; + } + + public function getCustomUrl(): ?string { + return $this->customUrl; + } + + public function setCustomUrl( string $customUrl ): self { + $this->customUrl = $customUrl; + + return $this; + } + + public function getPassword(): ?string { + return $this->password; + } + + public function setPassword( string $password ): self { + $this->password = md5( $password ); + + return $this; + } + + public function getModificationPolicy(): ?string { + return $this->modificationPolicy; + } + + public function setModificationPolicy( string $modificationPolicy ): self { + $this->modificationPolicy = $modificationPolicy; + + return $this; + } + + public function getMailOnComment(): ?bool { + return $this->mailOnComment; + } + + public function setMailOnComment( bool $mailOnComment ): self { + $this->mailOnComment = $mailOnComment; + + return $this; + } + + public function getMailOnVote(): ?bool { + return $this->mailOnVote; + } + + public function setMailOnVote( bool $mailOnVote ): self { + $this->mailOnVote = $mailOnVote; + + return $this; + } + + public function getHideResults(): ?bool { + return $this->hideResults; + } + + public function setHideResults( bool $hideResults ): self { + $this->hideResults = $hideResults; + + return $this; + } + + public function getShowResultEvenIfPasswords(): ?bool { + return $this->showResultEvenIfPasswords; + } + + public function setShowResultEvenIfPasswords( bool $showResultEvenIfPasswords ): self { + $this->showResultEvenIfPasswords = $showResultEvenIfPasswords; + + return $this; + } + + + /** + * @return Collection|Comment[] + */ + public function getComments(): Collection { + return $this->comments; + } + + public function addComment( Comment $comment ): self { + if ( ! $this->comments->contains( $comment ) ) { + $this->comments[] = $comment; + $comment->setPoll( $this ); } + + return $this; } - return $this; - } + public function removeComment( Comment $comment ): self { + if ( $this->comments->contains( $comment ) ) { + $this->comments->removeElement( $comment ); + // set the owning side to null (unless already changed) + if ( $comment->getPoll() === $this ) { + $comment->setPoll( null ); + } + } - public function addChoice( Choice $choice ): self { - if ( ! is_null( $this->choices ) ) { - if ( ! $this->choices->contains( $choice ) ) { + return $this; + } + + public function getStacksOfVotes() { + return $this->stacksOfVotes; + } + + public function setStacksOfVotes( ?StackOfVotes $stacksOfVotes ): self { + $this->stacksOfVotes = $stacksOfVotes; + + return $this; + } + + + public function addStackOfVote( StackOfVotes $stackOfVote ): self { + if ( ! $this->stacksOfVotes->contains( $stackOfVote ) ) { + $this->stacksOfVotes[] = $stackOfVote; + $stackOfVote->setPoll( $this ); + } + + return $this; + } + + public function removeStackOfVote( StackOfVotes $stackOfVote ): self { + if ( $this->stacksOfVotes->contains( $stackOfVote ) ) { + $this->stacksOfVotes->removeElement( $stackOfVote ); + // set the owning side to null (unless already changed) + if ( $stackOfVote->getPoll() === $this ) { + $stackOfVote->setPoll( null ); + } + } + + return $this; + } + + public function getExpiracyDate(): ?\DateTimeInterface { + return $this->expiracyDate; + } + + public function addVote( Vote $vote ): self { + if ( ! $this->votes->contains( $vote ) ) { + $this->votes[] = $vote; + $vote->setPoll( $this ); + } + + return $this; + } + + public function removeVote( Vote $vote ): self { + if ( $this->votes->contains( $vote ) ) { + $this->votes->removeElement( $vote ); + // set the owning side to null (unless already changed) + if ( $vote->getPoll() === $this ) { + $vote->setPoll( null ); + } + } + + return $this; + } + + /** + * @return Collection|Choice[] + */ + public function getChoices(): Collection { + return $this->choices; + } + + public function addTextChoiceArray( Array $choiceTextArray ): self { + foreach ( $choiceTextArray as $text ) { + $newChoice = new Choice(); + $newChoice->setName( $text ); + $this->addChoice( $newChoice ); + } + + return $this; + } + + + public function getAllowedAnswers(): ?array { + return $this->allowedAnswers; + } + + public function setAllowedAnswers( array $allowedAnswers ): self { + $this->allowedAnswers = $allowedAnswers; + + return $this; + } + + public function addStacksOfVote( StackOfVotes $stacksOfVote ): self { + if ( ! $this->stacksOfVotes->contains( $stacksOfVote ) ) { + $this->stacksOfVotes[] = $stacksOfVote; + $stacksOfVote->setPoll( $this ); + } + + return $this; + } + + public function removeStacksOfVote( StackOfVotes $stacksOfVote ): self { + if ( $this->stacksOfVotes->contains( $stacksOfVote ) ) { + $this->stacksOfVotes->removeElement( $stacksOfVote ); + // set the owning side to null (unless already changed) + if ( $stacksOfVote->getPoll() === $this ) { + $stacksOfVote->setPoll( null ); + } + } + + return $this; + } + + public function addChoice( Choice $choice ): self { + if ( ! is_null( $this->choices ) ) { + if ( ! $this->choices->contains( $choice ) ) { + $this->choices[] = $choice; + $choice->setPoll( $this ); + } + } else { $this->choices[] = $choice; $choice->setPoll( $this ); } - } else { - $this->choices[] = $choice; - $choice->setPoll( $this ); + + + return $this; } - - return $this; - } - - public function removeChoice( Choice $choice ): self { - if ( $this->choices->contains( $choice ) ) { - $this->choices->removeElement( $choice ); - // set the owning side to null (unless already changed) - if ( $choice->getPoll() === $this ) { - $choice->setPoll( null ); + public function removeChoice( Choice $choice ): self { + if ( $this->choices->contains( $choice ) ) { + $this->choices->removeElement( $choice ); + // set the owning side to null (unless already changed) + if ( $choice->getPoll() === $this ) { + $choice->setPoll( null ); + } } - } - return $this; + return $this; + } } -}