findAll(); $polls = $data; $titles = []; $pollData = [ 'message' => 'here are your polls', 'count' => count($polls), ]; $debug = 1; if ($debug) { foreach ($polls as $poll) { $titles[] = [ 'title' => $poll->getTitle(), 'slug' => $poll->getCustomUrl(), ]; } $pollData['polls'] = $titles; } return $this->json($pollData); } /** * get a poll config by its public custom URL, we do not want polls to be reachable by their numeric id * @Get( * path = "/{customUrl}", * name = "get_poll" * ) * * @param SerializerInterface $serializer * @param Request $request * * @return JsonResponse|Response */ public function getPollConfig( SerializerInterface $serializer, $customUrl, Request $request ) { $repository = $this->getDoctrine()->getRepository(Poll::class); $poll = $repository->findOneByCustomUrl($customUrl); if (!$poll) { return $this->notFoundPoll($customUrl); } $comments = $poll->getComments(); $stacks = $poll->getStacksOfVotes(); $pass = $poll->getPassword(); /** * 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 $pollResult = $poll->display(); return $this->json($pollResult); } } /** * @param $id * message when the poll is not found * * @return JsonResponse */ public function notFoundPoll($id): Response { 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 = "/owner/{owner_email}/", * name = "get_owner_poll", * ) * * @return JsonResponse|Response */ function getOwnerPolls($owner_email, LoggerInterface $logger) { $repository = $this->getDoctrine()->getRepository(Owner::class); $owner = $repository->findOneByEmail($owner_email); if (!$owner) { return $this->json(['message' => "Owner $owner_email non trouvé"], 404); } else { $polls = $owner->getPolls(); $pollsDisplay = []; foreach ($polls as $p) { $pollsDisplay[] = $p->displayForAdmin(); } $mail_sent = $this->sendOwnerPollsAction($owner); $logger->info('getOwnerPolls : Email sent : ' . $mail_sent); return $this->json(['mail_sent' => $mail_sent], $mail_sent ? 200 : 404); // return $this->json(['owner' => $owner->displayForAdmin(), 'polls' => $pollsDisplay], 200); } } /** * get a poll config by its custom URL, we do not want polls to be reachable by their numeric id * @Get( * path = "/{customUrl}/pass/{md5}", * name = "get_protected_poll", * ) * * @param SerializerInterface $serializer * @param Request $request * * @return JsonResponse|Response */ function getProtectedPoll($customUrl, $md5, SerializerInterface $serializer) { $repository = $this->getDoctrine()->getRepository(Poll::class); $poll = $repository->findOneByCustomUrl($customUrl); if (!$poll) { return $this->notFoundPoll($customUrl); } if (md5($poll->getPassword()) === $md5) { // good matching pass return $this->json($poll->display()); } else { // wrong pass return $this->json([ 'message' => 'this is protected by a password, your password hash "' . $md5 . '" is wrong, and you should feel bad', 'pass' => $md5, 'md5' => md5($md5), 'md5( $poll->getPassword() )' => md5($poll->getPassword()), 'data' => null, ], 403); } } /** * as an administrator of a poll, * get a poll config by its custom URL, * we do not want polls to be reachable by their numeric id * @Get( * path = "admin/{admin_key}", * name = "get_admin_poll", * ) * * @param SerializerInterface $serializer * @param Request $request * * @return JsonResponse|Response */ function getAdminPoll($admin_key, $md5, SerializerInterface $serializer) { $repository = $this->getDoctrine()->getRepository(Poll::class); $poll = $repository->findOneByAdminKey($admin_key); if (!$poll) { return $this->notFoundPoll($admin_key); } // good matching pass return $this->json($poll->displayForAdmin()); } /** * @param $poll * @param $serializer * @return Response */ 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 = "/{customUrl}/update/{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($poll->displayForAdmin() , 200); } /** * @Post( * path = "/", * name = "new_poll" * ) * @param Request $request * create a new poll * @return JsonResponse */ public function newPollAction(Request $request): JsonResponse { $data = $request->getContent(); $data = json_decode($data, true); // search for existing custom url, which must be unique if(! isset($data) || !isset($data['custom_url'])){ return $this->json(["message"=> 'NOPE, pas de data ou de custom url'], 403 ); } $custom_url = $data['custom_url']; $repository = $this->getDoctrine()->getRepository(Poll::class); $poll = $repository->findOneByCustomUrl($custom_url); if ($poll) { return $this->json(["message"=> 'NOPE, ce sondage existe déjà: ' . $custom_url], 403 ); } $newpoll = new Poll(); $newpoll ->setModificationPolicy(isset($data['modification_policy']) ? $data['modification_policy'] : 'everybody') ->setTitle($data['title']) ->setKind($data['kind']) ->setCustomUrl($custom_url); if (count($data['allowed_answers'])) { // TODO check this one $newpoll->setAllowedAnswers($data['allowed_answers']); } // define a maximum expiration $expiracyCalculated = min($newpoll->addDaysToDate(new DateTime(), $data['default_expiracy_days_from_now']), $newpoll->addDaysToDate(new DateTime(), 360)); $newpoll->setExpiracyDate($expiracyCalculated); $emOwner = $this->getDoctrine()->getRepository(Owner::class); $foundOwner = $emOwner->findOneByEmail($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($data['isOwnerNotifiedByEmailOnNewVote']); $newpoll->setMailOnComment($data['isOwnerNotifiedByEmailOnNewComment']); $newpoll->setIsZeroKnowledge($data['is_zero_knowledge']); $newpoll->setDescription($data['description']); $newpoll->setHideResults($data['hideResults']); // possible answers $newpoll->setAllowedAnswers($data['allowed_answers']); $newpoll->setVotesMax($data['maxCountOfAnswers']); $newpoll->setCommentsAllowed($data['allowComments']); // setup the password, converting the raw with md5 hash if ($data['password']) { $newpoll->setPassword($data['password']); } $choices_debug = ''; // text kind of answers, dates are below if ($data['kind'] == 'text') { // manage choices $choices = $data['choicesText']; foreach ($choices as $c) { $newChoice = new Choice(); $newChoice ->setPoll($newpoll) ->setName($c['literal']); $em->persist($newChoice); $newpoll->addChoice($newChoice); } } // date kind of poll elseif ($data['kind'] == 'date') { $choices = $data['dateChoices']; $choices_debug .= 'debug count recieved' . count($choices); if (isset($data['hasSeveralHours']) && $data['hasSeveralHours'] == true) { // different hours spans make more choices foreach ($choices as $c) { $currentDate = $c['literal']; $timeSlicesOfThisChoice = $c['timeSlices']; foreach ($timeSlicesOfThisChoice as $t) { $newChoice = new Choice(); $newChoice ->setPoll($newpoll) ->setName($currentDate . ' >>> ' . $t['literal']); $em->persist($newChoice); $newpoll->addChoice($newChoice); } } } else { // all choices will be having the same time slices from timeSlices $timeSlicesForAllChoices = $data['timeSlices']; foreach ($choices as $c) { $currentDate = $c['date_object']; foreach ($timeSlicesForAllChoices as $t) { $newChoice = new Choice(); $newChoice ->setPoll($newpoll) ->setName($currentDate . ' >>> ' . $t['literal']); $em->persist($newChoice); $newpoll->addChoice($newChoice); } } } } $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 the poll ' . $newpoll->getCustomUrl() . ' ' . $precision, 'debug' => $choices_debug, 'id' => $newpoll->getId(), 'poll' => $newpoll->displayForAdmin(), 'password_protected' => is_string($newpoll->getPassword()), ], 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(Poll::class); $foundPoll = $em->findOneByCustomUrl('dessin-anime'); $em = $this->getDoctrine()->getRepository(Owner::class); $foundOwner = $em->findOneByEmail($emailChoice); return $this->render('emails/creation-mail.html.twig', ['poll' => $foundPoll, 'owner' => $foundPoll->getOwner()]); } /** * @Delete( * path = "/{admin_key}", * name = "poll_delete", * requirements = {"accessToken"="\w+", "poll_id"="\d+"} * ) * @param Poll $poll * @param $accessToken * * @return JsonResponse */ public function deletePollAction( $admin_key ) { $emPoll = $this->getDoctrine()->getRepository(Poll::class); $found = $emPoll->findOneByAdminKey($admin_key); if ($found) { $em = $this->getDoctrine()->getManager(); $em->remove($found); $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/{customUrl}", * name = "check_slug_is_unique", * ) */ public function checkSlugIsUniqueAction(string $customUrl) { $emPoll = $this->getDoctrine()->getRepository(Poll::class); $found = $emPoll->findOneByCustomUrl($customUrl); $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 custom_url is already taken on this Framadate instance ', 'data' => [ 'slug' => $customUrl, ], ], 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' => $customUrl, ], ], 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; $returnedPoll = [ 'message' => 'your poll config', 'poll' => $poll->displayForAdmin(), ]; return $this->json($returnedPoll, 200);; } return $this->json([ 'message' => 'You are not allowed to do anything with this token', 'data' => [ 'token' => $token, ], ], 403); } /** * Find expired polls and set them as such * @Get( * path = "/admin/clean_expired_polls/{token}", * name = "clean_expired_polls", * ) * * @param $token * * @return JsonResponse|Response */ public function getExpiredPollsCleanup($token) { if ($token !== 'superCaligistriixpirlidouciousse') { return $this->json([ 'message' => 'not allowed', 'data' => [ 'token' => $token, ], ], 403); } $em = $this->getDoctrine()->getManager(); $emPoll = $this->getDoctrine()->getRepository(Poll::class); $deletablePollsFound = $emPoll->findDeletableExpiredPolls(); // dead by more than 30 days $expiredPollsFound = $emPoll->findExpiredPolls(); // just dead $soon_expired_polls = $emPoll->findSoonExpiredPolls(); // will die in 30 days $deletedTitle = []; $expiredTitle = []; $soon_expired_title = []; $really_delete = false; foreach ($soon_expired_polls as $item) { $soon_expired_title[] = $item->getTitle(); } foreach ($expiredPollsFound as $item) { $expiredTitle[] = $item->getTitle(); $item->setVotesAllowed(false); $em->persist($item); } foreach ($deletablePollsFound as $item) { $deletedTitle[] = $item->getTitle(); if ($really_delete) { $item->setVotesAllowed(false); $em->remove($item); } } $em->flush(); return $this->json([ 'message' => 'cleanup report', 'really_delete' => $really_delete, 'deleted' => count($deletablePollsFound), 'deleted_titles' => $deletedTitle, 'expired' => count($expiredPollsFound), 'expired_titles' => $expiredTitle, 'soon_to_be_expired' => count($soon_expired_polls), 'soon_to_be_expired_titles' => $soon_expired_title, 'data' => [ 'token' => $token, ], ], 200); } }