date-poll-api/src/Controller/PollController.php

411 lines
10 KiB
PHP
Raw Normal View History

2020-01-30 11:28:24 +01:00
<?php
namespace App\Controller;
use App\Entity\Choice;
use App\Entity\Owner;
use App\Entity\Poll;
2020-01-30 11:31:23 +01:00
use FOS\RestBundle\Controller\Annotations\Delete;
2020-01-30 11:28:24 +01:00
use FOS\RestBundle\Controller\Annotations\Get;
2020-01-30 11:31:23 +01:00
use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\Put;
2020-01-30 11:28:24 +01:00
use FOS\RestBundle\Controller\Annotations\Route;
use JMS\Serializer\Exception\RuntimeException;
2020-01-30 11:28:24 +01:00
use JMS\Serializer\SerializerBuilder;
use JMS\Serializer\SerializerInterface;
2020-04-16 17:11:01 +02:00
use Swift_Mailer;
2020-01-30 11:28:24 +01:00
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
2020-01-30 11:28:24 +01:00
/**
* Class DefaultController
* @package App\Controller
* @Route("/api/v1/poll",name="api_")
*/
2020-04-16 17:11:01 +02:00
class PollController extends FramadateController {
2020-01-30 11:28:24 +01:00
/**
* @Get(
* path = "/",
* 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 = "/{id}",
* name = "get_poll",
* requirements = {"poll_id"="\d+"}
* )
* @param SerializerInterface $serializer
* @param Poll $poll
* @param Request $request
*
* @return JsonResponse|Response
*/
public function getPollConfig(
SerializerInterface $serializer,
Poll $poll,
Request $request
) {
2020-01-30 11:28:24 +01:00
$pass = $poll->getPassword();
$data = $request->getContent();
$data = json_decode( $data, true );
$comments = $poll->getComments();
2020-01-30 11:28:24 +01:00
$returnedPoll = [
'message' => 'your poll config',
'poll' => $poll,
'stacks_count' => count( $poll->getStacksOfVotes() ),
'stacks' => $poll->getStacksOfVotes(),
2020-01-30 11:28:24 +01:00
'choices_count' => $poll->computeAnswers(),
'choices' => $poll->getChoices(),
2020-01-30 11:28:24 +01:00
'comments' => $comments,
'comments_count' => count( $comments ),
];
2020-01-30 11:28:24 +01:00
/**
* password protected content
*/
if ( $pass && $pass !== md5($data[ 'password_input' ])) {
return $this->json( [
'message' => 'your password ' . $data[ 'password_input' ] . ' is wrong, and you should feel bad',
'data' => null,
],
403 );
2020-01-30 11:28:24 +01:00
} else {
$jsonResponse = $serializer->serialize($returnedPoll, 'json');
$response = new Response($jsonResponse);
$response->headers->set('Content-Type', 'application/json');
$response->setStatusCode(200);
return $response;
2020-01-30 11:28:24 +01:00
}
}
/**
* @Put(
2020-04-17 16:12:35 +02:00
* path = "/{id}/{token}",
2020-01-30 11:28:24 +01:00
* name = "update_poll",
* requirements = {"content"="\w+", "poll_id"="\d+"}
* )
*/
public function updatePollConfig(
2020-01-30 11:28:24 +01:00
Poll $poll,
2020-04-17 16:12:35 +02:00
string $token,
2020-01-30 11:28:24 +01:00
Request $request
) {
2020-04-17 16:12:35 +02:00
if ( $poll->getAdminKey() !== $token ) {
return $this->json( [
'message' => 'you are NOT allowed to update the poll ' . $poll->getTitle(),
],
403 );
}
2020-01-30 11:28:24 +01:00
// 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(),
2020-04-17 16:12:59 +02:00
],
200 );
2020-01-30 11:28:24 +01:00
}
/**
* @Post(
* path = "/",
* name = "new_poll",
* requirements = {"creator"="\w+"}
* )
* @param Request $request
*
* @return JsonResponse
*/
2020-04-16 17:51:49 +02:00
public function newPollAction( Request $request ) {
2020-01-30 11:28:24 +01:00
$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);
}
2020-01-30 11:28:24 +01:00
$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 ?
2020-01-30 11:28:24 +01:00
// 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 );
2020-04-10 18:02:52 +02:00
2020-01-30 11:28:24 +01:00
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 );
}
2020-04-10 18:02:52 +02:00
/**
* @Get(
2020-04-12 17:28:30 +02:00
* path = "/mail/test-mail-poll/{emailChoice}",
2020-04-10 18:02:52 +02:00
* name = "test-mail-poll",
* )
*
* send the creation mail to owner
*
* @param Owner $admin_user
* @param Poll $poll
2020-04-16 17:11:01 +02:00
* @param Swift_Mailer $mailer
2020-04-10 18:02:52 +02:00
*
* @return int
2020-04-16 17:11:01 +02:00
* not that the email tktest_commentateur@tktest.com does not really exist
2020-04-10 18:02:52 +02:00
*/
// public function sendCreationMailAction( Owner $admin_user, Poll $poll, \Swift_Mailer $mailer) {
2020-04-16 17:11:01 +02:00
public function testSendCreationMailAction(
$emailChoice = 'tktest_commentateur@tktest.com'
) {
2020-04-10 18:02:52 +02:00
$em = $this->getDoctrine()->getRepository( Owner::class );
2020-04-16 16:43:30 +02:00
$foundOwner = $em->findOneByEmail( $emailChoice );
2020-04-16 17:11:01 +02:00
if ( $foundOwner ) {
$poll = $foundOwner->getPolls()[ 0 ];
$comment = $foundOwner->getComments()[ 0 ];
2020-04-16 16:43:30 +02:00
2020-04-16 18:03:09 +02:00
$sent = $this->sendOwnerPollsAction( $foundOwner, $poll );
2020-04-16 17:11:01 +02:00
if ( $sent ) {
2020-04-17 16:02:23 +02:00
return $this->json( [ "message" => "test email sent to " . $foundOwner->getEmail() . "!" ], 200 );
2020-04-16 16:43:30 +02:00
}
}
2020-04-16 17:11:01 +02:00
return $this->json( [ "message" => "user with this email was not found" ], 400 );
2020-04-12 17:28:30 +02:00
2020-04-10 18:02:52 +02:00
}
2020-01-30 11:28:24 +01:00
/**
* @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',
] );
}
}
2020-04-17 16:02:23 +02:00
/**
2020-04-17 16:12:35 +02:00
* Check is a slug is already taken by a poll
2020-04-17 16:02:23 +02:00
* @Get(
2020-04-21 18:03:18 +02:00
* path = "/slug/{slug}",
2020-04-17 16:02:23 +02:00
* name = "check_slug_is_unique",
* )
*/
public function checkSlugIsUniqueAction( string $slug ) {
2020-04-21 18:11:39 +02:00
$emPoll = $this->getDoctrine()->getRepository( Poll::class );
$found = $emPoll->findOneByCustomUrl( $slug );
$elaborated_message_version = false;
2020-04-17 16:02:23 +02:00
if ( $found ) {
2020-04-21 18:11:39 +02:00
if ( ! $elaborated_message_version ) {
2020-04-21 18:26:38 +02:00
return $this->json( null,
2020-04-21 18:21:03 +02:00
204 );
2020-04-21 18:11:39 +02:00
}
// we should use an other slug
2020-04-17 16:02:23 +02:00
return $this->json( [
'message' => ' NO, this slug is already taken on this Framadate instance ',
'data' => [
'slug' => $slug,
],
],
2020-04-21 18:21:03 +02:00
204 );
2020-04-21 18:11:39 +02:00
}
if ( ! $elaborated_message_version ) {
2020-04-21 18:26:38 +02:00
return $this->json( null,
2020-04-21 18:11:39 +02:00
404 );
2020-04-17 16:02:23 +02:00
}
return $this->json( [
'message' => ' yes this slug is available on this Framadate instance ',
'data' => [
'slug' => $slug,
],
],
2020-04-21 18:11:39 +02:00
404 );
2020-04-17 16:02:23 +02:00
}
/**
* 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 ) {
2020-04-17 16:12:35 +02:00
$emPoll = $this->getDoctrine()->getRepository( Poll::class );
$pollFound = $emPoll->findOneByAdminKey( $token );
2020-04-17 16:12:35 +02:00
if ( $pollFound ) {
$poll = $pollFound;
$comments = $poll->getComments();
$stacks = $poll->getStacksOfVotes();
2020-04-17 16:12:35 +02:00
$returnedPoll = [
'message' => 'your poll config',
'poll' => $poll,
'stacks_count' => count( $stacks ),
2020-04-17 16:12:35 +02:00
'stacks' => $stacks,
'choices_count' => $poll->computeAnswers(),
'choices' => $poll->getChoices(),
2020-04-17 16:12:35 +02:00
'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;
2020-04-17 16:12:35 +02:00
}
return $this->json( [
'message' => 'You are not allowed to do anything with this token',
'data' => [
'token' => $token,
],
],
403 );
}
2020-01-30 11:28:24 +01:00
}