getDoctrine()->getRepository( Poll::class ); $data = $repository->findAll(); return $this->json( [ 'message' => 'here are your polls', 'poll' => count( $data ), ] ); } /** * @param $id * message when the poll is not found * @return JsonResponse */ public function notFoundPoll($id){ return $this->json( [ 'message' => $id . ' : poll not found', ], 404 ); } /** * get a poll config by its custom URL, we do not want polls to be reachable by their numeric id * @Get( * path = "/{id}", * name = "get_poll", * requirements = {"id"="\w+"} * ) * * @param SerializerInterface $serializer * @param Request $request * * @return JsonResponse|Response */ public function getPollConfig( SerializerInterface $serializer, $id, Request $request ) { $repository = $this->getDoctrine()->getRepository( Poll::class ); $poll = $repository->findOneByCustomUrl( $id ); if ( ! $poll ) { return $this->notFoundPoll($id); } $comments = $poll->getComments(); $pass = $poll->getPassword(); $returnedPoll = [ 'message' => 'your poll config for ' . $poll->getTitle(), 'password_protected' => $pass ? 'yes' : 'no', // TODO do not render sub objects of owner, it returns too many things 'poll' => $poll, 'stacks_count' => count( $poll->getStacksOfVotes() ), 'stacks' => $poll->getStacksOfVotes(), 'choices_count' => $poll->computeAnswers(), 'choices' => $poll->getChoices(), 'comments' => $comments, 'comments_count' => count( $comments ), ]; /** * password protected content */ if ( $pass ) { // no password possibly given by this route return $this->json( [ 'message' => 'this is protected by a password,but you did not provide the encoded password parameter, and you should feel bad. ' , ], 403 ); } else { // free access to poll return $this->returnPollData( $poll, $serializer ); } } /** * get a poll config by its custom URL, we do not want polls to be reachable by their numeric id * @Get( * path = "/{id}/pass/{md5}", * name = "get_protected_poll", * requirements = {"id"="\w+"} * ) * * @param SerializerInterface $serializer * @param Request $request * * @return JsonResponse|Response */ function getProtectedPoll($id,$md5, SerializerInterface $serializer){ $repository = $this->getDoctrine()->getRepository( Poll::class ); $poll = $repository->findOneByCustomUrl( $id ); if ( ! $poll ) { return $this->notFoundPoll($id); } if ( $poll->getPassword() === $md5 ) { // good matching pass return $this->returnPollData( $poll, $serializer ); } else { // wrong pass return $this->json( [ 'message' => 'this is protected by a password, your password "' . $md5 . '" is wrong, and you should feel bad', 'md5' => md5($md5), 'data' => null, ], 403 ); } } function returnPollData( $poll, $serializer ) { $jsonResponse = $serializer->serialize( $poll, 'json' ); $response = new Response( $jsonResponse ); $response->headers->set( 'Content-Type', 'application/json' ); $response->setStatusCode( 200 ); return $response; } /** * @Put( * path = "/{id}/{token}", * name = "update_poll", * requirements = {"content"="\w+", "poll_id"="\d+"} * ) */ public function updatePollConfig( Poll $poll, string $token, Request $request ) { if ( $poll->getAdminKey() !== $token ) { return $this->json( [ 'message' => 'you are NOT allowed to update the poll ' . $poll->getTitle(), ], 403 ); } // 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(), ], 200 ); } /** * @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(); try { $newpoll = $serializer->deserialize( $data, 'App\Entity\Poll', 'json' ); } catch ( RuntimeException $e ) { return $this->json( [ "message" => "Incorrect JSON in request" ], 400 ); } $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 { //TODO (Sébastien) I assume this shouldn't be empty ? // all days have the same hour spans } } $em->persist( $newpoll ); $em->flush(); $precision = ''; if ( $userWasFound ) { $precision = 'from an existing user : ' . $foundOwner->getEmail(); } $this->sendCreationMailAction( $foundOwner, $newpoll ); 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 = "/mail/test-mail-poll/{emailChoice}", * name = "test-mail-poll", * ) * * send the creation mail to owner * * @param Owner $admin_user * @param Poll $poll * @param Swift_Mailer $mailer * * @return int * not that the email tktest_commentateur@tktest.com does not really exist */ // public function sendCreationMailAction( Owner $admin_user, Poll $poll, \Swift_Mailer $mailer) { public function testSendCreationMailAction( $emailChoice = 'tktest_commentateur@tktest.com' ) { $em = $this->getDoctrine()->getRepository( Owner::class ); $foundOwner = $em->findOneByEmail( $emailChoice ); if ( $foundOwner ) { $poll = $foundOwner->getPolls()[ 0 ]; $comment = $foundOwner->getComments()[ 0 ]; $sent = $this->sendOwnerPollsAction( $foundOwner, $poll ); if ( $sent ) { return $this->json( [ "message" => "test email sent to " . $foundOwner->getEmail() . "!" ], 200 ); } } return $this->json( [ "message" => "user with this email was not found" ], 400 ); } /** * @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', ] ); } } /** * Checks if a slug is already taken by a poll * @Get( * path = "/slug/{slug}", * name = "check_slug_is_unique", * ) */ public function checkSlugIsUniqueAction( string $slug ) { $emPoll = $this->getDoctrine()->getRepository( Poll::class ); $found = $emPoll->findOneByCustomUrl( $slug ); $elaborated_message_version = false; if ( $found ) { if ( ! $elaborated_message_version ) { return $this->json( null, 204 ); } // we should use an other slug return $this->json( [ 'message' => ' NO, this slug is already taken on this Framadate instance ', 'data' => [ 'slug' => $slug, ], ], 204 ); } if ( ! $elaborated_message_version ) { return $this->json( null, 404 ); } return $this->json( [ 'message' => ' yes this slug is available on this Framadate instance ', 'data' => [ 'slug' => $slug, ], ], 404 ); } /** * Get Admin poll config * @Get( * path = "/admin/{token}", * name = "get_admin_config", * ) * * @param SerializerInterface $serializer * @param $token * * @return JsonResponse|Response */ public function getAdministrationConfig( SerializerInterface $serializer, $token ) { $emPoll = $this->getDoctrine()->getRepository( Poll::class ); $pollFound = $emPoll->findOneByAdminKey( $token ); if ( $pollFound ) { $poll = $pollFound; $comments = $poll->getComments(); $stacks = $poll->getStacksOfVotes(); $returnedPoll = [ 'message' => 'your poll config', 'poll' => $poll, 'stacks_count' => count( $stacks ), 'stacks' => $stacks, 'choices_count' => $poll->computeAnswers(), 'choices' => $poll->getChoices(), 'comments' => $comments, 'comments_count' => count( $comments ), 'token' => $token, ]; $jsonResponse = $serializer->serialize( $returnedPoll, 'json' ); $response = new Response( $jsonResponse ); $response->headers->set( 'Content-Type', 'application/json' ); $response->setStatusCode( 200 ); return $response; } return $this->json( [ 'message' => 'You are not allowed to do anything with this token', 'data' => [ 'token' => $token, ], ], 403 ); } }