From 39722aba29a40e757284975c1949c9934154361c Mon Sep 17 00:00:00 2001 From: Baptiste Lemoine Date: Thu, 30 Jan 2020 11:28:24 +0100 Subject: [PATCH] :zap: split controllers --- README.md | 2 +- src/Controller/CommentController.php | 160 ++++++ src/Controller/DefaultController.php | 697 +++------------------------ src/Controller/PollController.php | 307 ++++++++++++ src/Controller/VoteController.php | 165 +++++++ 5 files changed, 687 insertions(+), 644 deletions(-) create mode 100644 src/Controller/CommentController.php create mode 100644 src/Controller/PollController.php create mode 100644 src/Controller/VoteController.php diff --git a/README.md b/README.md index 9978515..6bca0f5 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ this file is not versionned and should stay like this. ## cronjob to delete expired polls add this line in your crontab to run the clearance of expired polls everyday at 0h00. ``` -0 0 * * * wget http://MYWEBSITE/api/v1/clean-polls +0 0 * * * wget http://MYWEBSITE/api/v1/poll/clean-polls ``` you can open your crontabl in command line with : ``` diff --git a/src/Controller/CommentController.php b/src/Controller/CommentController.php new file mode 100644 index 0000000..1ee0f17 --- /dev/null +++ b/src/Controller/CommentController.php @@ -0,0 +1,160 @@ +json( [ + 'message' => 'here are your comments of the poll', + 'data' => $poll->getComments(), + ], + 200 ); + } + + /** + * 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 ); + } + + /** + * 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', + ] ); + } + } + +} diff --git a/src/Controller/DefaultController.php b/src/Controller/DefaultController.php index 68c9851..6933d5f 100644 --- a/src/Controller/DefaultController.php +++ b/src/Controller/DefaultController.php @@ -1,660 +1,71 @@ getDoctrine()->getRepository( Owner::class ); + $founduser = $repository->findOneBy( [ 'email' => $email ] ); - - /** - * @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 = "/polls", - * name = "get_all_polls" - * ) - */ - public function getAllPollsAction() { - $repository = $this->getDoctrine()->getRepository( Poll::class ); - $data = $repository->findall(); - - - return $this->json( [ - 'message' => 'here are your polls', - 'poll' => $data, - ], - 200 ); - } - - /** - * @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( - 'emails/owner-list.html.twig', - $templateVars - ) - ); - $mailer->send( $message ); - - return $this->render( 'emails/owner-list.html.twig', $templateVars ); - - } 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 ); - - } - - /** - * @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' => $poll->computeAnswers(), - 'choices' => $choices, - 'comments' => $comments, - 'comments_count' => count( $comments ), + if ( $founduser ) { + $polls = $founduser->getPolls(); + $templateVars = [ + 'owner' => $founduser, + 'polls' => $polls, ]; - /** - * 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 ); - } + $message = ( new Swift_Message( 'Framadate - mes sondages' ) ) + ->setFrom( 'ne-pas-repondre@framadate-api.cipherbliss.com' ) + ->setTo( $founduser->getEmail() ) + ->setBody( + $this->renderView( + 'emails/owner-list.html.twig', + $templateVars + ) + ); + $mailer->send( $message ); - } - - /** - * 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->render( 'emails/owner-list.html.twig', $templateVars ); + } else { return $this->json( [ - 'message' => 'clean routine has been done, here are the numbers of polls deleted: ' . count( $foundPolls ), - 'data' => [ - 'count' => count( $foundPolls ), - ], + 'message' => 'no user found for email ' . $email, + 'data' => '', ], - 200 ); + 400 ); } + // find user by email + // send email + // user not found case - /** - * @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(); - } - $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(); - } - - return $this->json( [ - 'message' => 'you created a vote stack' . $precision, - 'poll' => $poll, - 'vote_stack' => $stack->display(), - 'stacks' => $stacks, - 'comments' => $comments, - 'choices' => $choices, - 'choices_count' => $poll->computeAnswers(), - '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/Controller/PollController.php b/src/Controller/PollController.php new file mode 100644 index 0000000..63895de --- /dev/null +++ b/src/Controller/PollController.php @@ -0,0 +1,307 @@ +getDoctrine()->getRepository( Poll::class ); + $data = $repository->findall(); + + + return $this->json( [ + 'message' => 'here are your polls', + 'poll' => $data, + ], + 200 ); + } + + /** + * @Get( + * path = "/{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 ); + } + + } + + /** + * @Put( + * path = "/{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(), + ] ); + } + + /** + * @Post( + * path = "/", + * 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 ); + + } + + + /** + * @Delete( + * path = "/{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', + ] ); + } + + } + + /** + * 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 ); + } + +} diff --git a/src/Controller/VoteController.php b/src/Controller/VoteController.php new file mode 100644 index 0000000..8f20658 --- /dev/null +++ b/src/Controller/VoteController.php @@ -0,0 +1,165 @@ +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(); + } + $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(); + } + + return $this->json( [ + 'message' => 'you created a vote stack' . $precision, + 'poll' => $poll, + 'vote_stack' => $stack->display(), + 'stacks' => $stacks, + 'comments' => $comments, + 'choices' => $choices, + 'choices_count' => $poll->computeAnswers(), + 'vote_count' => count( $poll->getStacksOfVotes() ), + 'owner_modifier_token' => $foundOwner->getModifierToken(), + 'admin_key' => $poll->getAdminKey(), + 'json_you_sent' => $data, + ], + 201 ); + } + + /** + * @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', + ] ); + } + + } +}