Merge branch 'contribatelier' into 'master'

Fix on Json Serialization

See merge request tykayn/date-poll-api!2
This commit is contained in:
ty kayn 2020-04-26 14:37:54 +02:00
commit 53ffaf8ed5
9 changed files with 163 additions and 145 deletions

View File

@ -26,6 +26,10 @@ install dependencies with Composer
there are examples of request to make it all work in the [doc/examples.md](doc/examples.md). there are examples of request to make it all work in the [doc/examples.md](doc/examples.md).
### Check prerequisites
```bash
composer check-platform-reqs
```
### install the vendors ### install the vendors
```bash ```bash

View File

@ -6,6 +6,7 @@
"ext-ctype": "*", "ext-ctype": "*",
"ext-iconv": "*", "ext-iconv": "*",
"ext-json": "*", "ext-json": "*",
"ext-pdo_mysql": "*",
"friendsofsymfony/rest-bundle": "^2.6", "friendsofsymfony/rest-bundle": "^2.6",
"jms/serializer-bundle": "^3.4", "jms/serializer-bundle": "^3.4",
"nelmio/api-doc-bundle": "^3.4", "nelmio/api-doc-bundle": "^3.4",

View File

@ -11,8 +11,10 @@ use FOS\RestBundle\Controller\Annotations\Get;
use FOS\RestBundle\Controller\Annotations\Post; use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\Route; use FOS\RestBundle\Controller\Annotations\Route;
use JMS\Serializer\SerializerBuilder; use JMS\Serializer\SerializerBuilder;
use JMS\Serializer\SerializerInterface;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/** /**
* Class DefaultController * Class DefaultController
@ -30,13 +32,19 @@ class CommentController extends FramadateController {
*/ */
public public
function getPollCommentsAction( function getPollCommentsAction(
Poll $poll SerializerInterface $serializer,
Poll $poll
) { ) {
return $this->json( [ $jsonResponse = $serializer->serialize([
'message' => 'here are your comments of the poll', 'message' => 'here are your comments of the poll',
'data' => $poll->getComments(), 'data' => $poll->getComments()], 'json');
],
200 ); $response = new Response($jsonResponse);
$response->headers->set('Content-Type', 'application/json');
$response->setStatusCode(200);
return $response;
} }
/** /**

View File

@ -11,9 +11,11 @@ use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\Put; use FOS\RestBundle\Controller\Annotations\Put;
use FOS\RestBundle\Controller\Annotations\Route; use FOS\RestBundle\Controller\Annotations\Route;
use JMS\Serializer\SerializerBuilder; use JMS\Serializer\SerializerBuilder;
use JMS\Serializer\SerializerInterface;
use Swift_Mailer; use Swift_Mailer;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/** /**
* Class DefaultController * Class DefaultController
@ -21,8 +23,6 @@ use Symfony\Component\HttpFoundation\Request;
* @Route("/api/v1/poll",name="api_") * @Route("/api/v1/poll",name="api_")
*/ */
class PollController extends FramadateController { class PollController extends FramadateController {
/** /**
* @Get( * @Get(
* path = "/", * path = "/",
@ -41,65 +41,57 @@ class PollController extends FramadateController {
200 ); 200 );
} }
/** /**
* @Get( * @Get(
* path = "/{id}", * path = "/{id}",
* name = "get_poll", * name = "get_poll",
* requirements = {"poll_id"="\d+"} * requirements = {"poll_id"="\d+"}
* ) * )
*/ * @param SerializerInterface $serializer
public * @param Poll $poll
function getPollConfig( * @param Request $request
Poll $poll, *
Request $request * @return JsonResponse|Response
) { */
public function getPollConfig(
SerializerInterface $serializer,
Poll $poll,
Request $request
) {
$pass = $poll->getPassword(); $pass = $poll->getPassword();
$data = $request->getContent(); $data = $request->getContent();
$data = json_decode( $data, true ); $data = json_decode( $data, true );
$comments = []; $comments = $poll->getComments();
$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 = [ $returnedPoll = [
'message' => 'your poll config', 'message' => 'your poll config',
'poll' => $poll, 'poll' => $poll,
'stacks_count' => count( $poll->getStacksOfVotes() ), 'stacks_count' => count( $poll->getStacksOfVotes() ),
'stacks' => $stacks, 'stacks' => $poll->getStacksOfVotes(),
'choices_count' => $poll->computeAnswers(), 'choices_count' => $poll->computeAnswers(),
'choices' => $choices, 'choices' => $poll->getChoices(),
'comments' => $comments, 'comments' => $comments,
'comments_count' => count( $comments ), 'comments_count' => count( $comments ),
]; ];
/** /**
* password protected content * password protected content
*/ */
if ( $pass ) { if ( $pass && $pass !== md5($data[ 'password_input' ])) {
return $this->json( [
if ( $pass == md5( $data[ 'password_input' ] ) ) { 'message' => 'your password ' . $data[ 'password_input' ] . ' is wrong, and you should feel bad',
return $this->json( 'data' => null,
$returnedPoll, ],
200 ); 403 );
} else {
return $this->json( [
'message' => 'your password ' . $data[ 'password_input' ] . ' is wrong, and you should feel bad',
'data' => null,
],
403 );
}
} else { } else {
return $this->json( $jsonResponse = $serializer->serialize($returnedPoll, 'json');
$returnedPoll
, $response = new Response($jsonResponse);
200 ); $response->headers->set('Content-Type', 'application/json');
$response->setStatusCode(200);
return $response;
} }
} }
@ -111,8 +103,7 @@ class PollController extends FramadateController {
* requirements = {"content"="\w+", "poll_id"="\d+"} * requirements = {"content"="\w+", "poll_id"="\d+"}
* ) * )
*/ */
public public function updatePollConfig(
function updatePollConfig(
Poll $poll, Poll $poll,
string $token, string $token,
Request $request Request $request
@ -220,7 +211,7 @@ class PollController extends FramadateController {
// different hours spans // different hours spans
$choices = $data[ 'dateList' ]; $choices = $data[ 'dateList' ];
} else { } else {
//TODO (Sébastien) I assume this shouldn't be empty ?
// all days have the same hour spans // all days have the same hour spans
} }
@ -359,46 +350,46 @@ class PollController extends FramadateController {
} }
/**
/** * Get Admin poll config
* Get Admin poll config * @Get(
* @Get( * path = "/admin/{token}",
* path = "/admin/{token}", * name = "get_admin_config",
* name = "get_admin_config", * )
* ) * @param SerializerInterface $serializer
*/ * @param $token
public function getAdministrationConfig( $token ) { *
* @return JsonResponse|Response
*/
public function getAdministrationConfig(SerializerInterface $serializer, $token ) {
$emPoll = $this->getDoctrine()->getRepository( Poll::class ); $emPoll = $this->getDoctrine()->getRepository( Poll::class );
$pollFound = $emPoll->findOneByAdminKey( $token ); $pollFound = $emPoll->findOneByAdminKey( $token );
if ( $pollFound ) { if ( $pollFound ) {
$poll = $pollFound; $poll = $pollFound;
$comments = []; $comments = $poll->getComments();
$stacks = []; $stacks = $poll->getStacksOfVotes();
$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 = [ $returnedPoll = [
'message' => 'your poll config', 'message' => 'your poll config',
'poll' => $poll, 'poll' => $poll,
'stacks_count' => count( $poll->getStacksOfVotes() ), 'stacks_count' => count( $stacks ),
'stacks' => $stacks, 'stacks' => $stacks,
'choices_count' => $poll->computeAnswers(), 'choices_count' => $poll->computeAnswers(),
'choices' => $choices, 'choices' => $poll->getChoices(),
'comments' => $comments, 'comments' => $comments,
'comments_count' => count( $comments ), 'comments_count' => count( $comments ),
'token' => $token, 'token' => $token,
]; ];
return $this->json( $returnedPoll, $jsonResponse = $serializer->serialize($returnedPoll, 'json');
200 );
$response = new Response($jsonResponse);
$response->headers->set('Content-Type', 'application/json');
$response->setStatusCode(200);
return $response;
} }
return $this->json( [ return $this->json( [

View File

@ -11,8 +11,10 @@ use FOS\RestBundle\Controller\Annotations\Delete;
use FOS\RestBundle\Controller\Annotations\Patch; use FOS\RestBundle\Controller\Annotations\Patch;
use FOS\RestBundle\Controller\Annotations\Post; use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\Route; use FOS\RestBundle\Controller\Annotations\Route;
use JMS\Serializer\SerializerInterface;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/** /**
* Class DefaultController * Class DefaultController
@ -21,18 +23,23 @@ use Symfony\Component\HttpFoundation\Request;
*/ */
class VoteController extends FramadateController { class VoteController extends FramadateController {
/** /**
* add a vote stack on a poll * add a vote stack on a poll
* @Post( * @Post(
* path = "/poll/{id}/vote", * path = "/poll/{id}/vote",
* name = "new_vote_stack", * name = "new_vote_stack",
* requirements = {"content"="\w+", "poll_id"="\d+"} * requirements = {"content"="\w+", "poll_id"="\d+"}
* ) * )
*/ * @param SerializerInterface $serializer
public * @param Poll $poll
function newVoteStackAction( * @param Request $request
Poll $poll, *
Request $request * @return JsonResponse|Response
*/
public function newVoteStackAction(
SerializerInterface $serializer,
Poll $poll,
Request $request
) { ) {
if ( ! $poll ) { if ( ! $poll ) {
return $this->json( [ 'message' => 'poll not found' ], 404 ); return $this->json( [ 'message' => 'poll not found' ], 404 );
@ -106,55 +113,57 @@ class VoteController extends FramadateController {
if ( $existingOwner ) { if ( $existingOwner ) {
$precision = ' from an existing owner : ' . $foundOwner->getEmail(); $precision = ' from an existing owner : ' . $foundOwner->getEmail();
} }
$comments = []; $stacks = $poll->getStacksOfVotes();
$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();
}
if($poll->getMailOnVote()){ if($poll->getMailOnVote()){
$this->sendVoteNotificationAction($stack->getOwner(), $stack); $this->sendVoteNotificationAction($stack->getOwner(), $stack);
} }
$returnedVoteStack = [
'message' => 'you created a vote stack' . $precision,
'poll' => $poll,
'vote_stack' => $stack,
'stacks' => $stacks,
'comments' => $poll->getComments(),
'choices' => $poll->getChoices(),
'choices_count' => $poll->computeAnswers(),
'vote_count' => count( $stacks ),
'owner' => $stack->getOwner(),
'owner_modifier_token' => $stack->getOwner()->getModifierToken(),
'admin_key' => $poll->getAdminKey(),
'json_you_sent' => $data,
];
$jsonResponse = $serializer->serialize($returnedVoteStack, 'json');
$response = new Response($jsonResponse);
$response->headers->set('Content-Type', 'application/json');
$response->setStatusCode(200);
return $response;
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' => $stack->getOwner(),
'owner_modifier_token' => $stack->getOwner()->getModifierToken(),
'admin_key' => $poll->getAdminKey(),
'json_you_sent' => $data,
],
201 );
} }
/** /**
* update vote stack * update vote stack
* @Patch( * @Patch(
* path = "/vote-stack/{id}/token/{modifierToken}", * path = "/vote-stack/{id}/token/{modifierToken}",
* name = "update_vote_stack", * name = "update_vote_stack",
* requirements = { "id"="\d+"} * requirements = { "id"="\d+"}
* ) * )
*/ * @param SerializerInterface $serializer
* @param StackOfVotes $id
* @param $modifierToken
* @param Request $request
*
* @return JsonResponse|Response
*/
public public
function updateVoteStackAction( function updateVoteStackAction(
StackOfVotes $id, SerializerInterface $serializer,
$modifierToken, StackOfVotes $id,
Request $request $modifierToken,
Request $request
) { ) {
$voteStack = $id; $voteStack = $id;
if ( ! $voteStack ) { if ( ! $voteStack ) {
@ -173,12 +182,18 @@ class VoteController extends FramadateController {
// update answers // update answers
// save evrything // save evrything
return $this->json( [
'message' => 'ok', $jsonResponse = $serializer->serialize([
'modifier_token' => $voteStack->getOwner()->getModifierToken(), 'message' => 'ok',
'vote_stack' => $voteStack->display(), 'modifier_token' => $voteStack->getOwner()->getModifierToken(),
], 'vote_stack' => $voteStack,
200 ); ], 'json');
$response = new Response($jsonResponse);
$response->headers->set('Content-Type', 'application/json');
$response->setStatusCode(200);
return $response;
} }

View File

@ -41,8 +41,6 @@ class Comment {
/** /**
* @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="comments") * @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="comments")
* @Serializer\Type("App\Entity\Poll")
* @Serializer\Expose()
*/ */
private $poll; private $poll;

View File

@ -10,7 +10,7 @@
/** /**
* @ORM\Entity(repositoryClass="App\Repository\PollRepository") * @ORM\Entity(repositoryClass="App\Repository\PollRepository")
* @Serializer\ExclusionPolicy("all") * @Serializer\ExclusionPolicy("all")
*/ */
class Poll { class Poll {
/** /**
@ -68,7 +68,7 @@
* array of possible answer to each choice, by default: "yes" or nothing only. * array of possible answer to each choice, by default: "yes" or nothing only.
* could be also "yes", "maybe", "no". extensible to anything * could be also "yes", "maybe", "no". extensible to anything
* @ORM\Column(type="array") * @ORM\Column(type="array")
* @Serializer\Type("string") * @Serializer\Type("array")
* @Serializer\Expose() * @Serializer\Expose()
*/ */
public $allowedAnswers; public $allowedAnswers;
@ -112,7 +112,7 @@
public $showResultEvenIfPasswords; public $showResultEvenIfPasswords;
/** /**
* @ORM\OneToMany(targetEntity="App\Entity\Vote", mappedBy="poll", orphanRemoval=true, cascade={"persist", "remove"}) * @ORM\OneToMany(targetEntity="App\Entity\Vote", mappedBy="poll", orphanRemoval=true, cascade={"persist", "remove"})
* @Serializer\Type("App\Entity\Vote") * @Serializer\Type("ArrayCollection<App\Entity\Vote>")
* @Serializer\Expose() * @Serializer\Expose()
*/ */
public $votes; public $votes;
@ -124,12 +124,13 @@
/** /**
* @ORM\OneToMany(targetEntity="App\Entity\Choice", mappedBy="poll", orphanRemoval=true, cascade={"persist", "remove"}) * @ORM\OneToMany(targetEntity="App\Entity\Choice", mappedBy="poll", orphanRemoval=true, cascade={"persist", "remove"})
* @Serializer\Expose() * @Serializer\Expose()
* @Serializer\Type("ArrayCollection<App\Entity\Choice>")
*/ */
public $choices; public $choices;
/** /**
* @ORM\OneToMany(targetEntity="App\Entity\Comment", mappedBy="poll", orphanRemoval=true, cascade={"persist", "remove"}) * @ORM\OneToMany(targetEntity="App\Entity\Comment", mappedBy="poll", orphanRemoval=true, cascade={"persist", "remove"})
* @Serializer\Expose() * @Serializer\Expose()
* @Serializer\Type("App\Entity\Comment") * @Serializer\Type("ArrayCollection<App\Entity\Comment>")
*/ */
public $comments; public $comments;
/** /**

View File

@ -11,6 +11,7 @@ use JMS\Serializer\Annotation as Serializer;
* contains the votes for one answer to a poll * contains the votes for one answer to a poll
* @ORM\Entity(repositoryClass="App\Repository\StackOfVotesRepository") * @ORM\Entity(repositoryClass="App\Repository\StackOfVotesRepository")
* @ORM\HasLifecycleCallbacks() * @ORM\HasLifecycleCallbacks()
* @Serializer\ExclusionPolicy("all")
*/ */
class StackOfVotes { class StackOfVotes {
/** /**
@ -32,7 +33,6 @@ class StackOfVotes {
public $votes; public $votes;
/** /**
* @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="stacksOfVotes", cascade={"persist"}) * @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="stacksOfVotes", cascade={"persist"})
* @Serializer\Expose()
*/ */
private $poll; private $poll;

View File

@ -8,10 +8,11 @@
/** /**
* @ORM\Entity(repositoryClass="App\Repository\VoteRepository") * @ORM\Entity(repositoryClass="App\Repository\VoteRepository")
* @Serializer\ExclusionPolicy("all")
*/ */
class Vote { class Vote {
/** /**
* for a text kind of choice: could be "yes" "no" "maybe" and emptu. * for a text kind of choice: could be "yes" "no" "maybe" and empty.
* for a date kind, the choice linked is equivalent to the value selected * for a date kind, the choice linked is equivalent to the value selected
* @ORM\Column(type="string", length=255, nullable=true) * @ORM\Column(type="string", length=255, nullable=true)
* @Serializer\Type("string") * @Serializer\Type("string")
@ -42,7 +43,6 @@
/** /**
* @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="votes", cascade={"persist"}) * @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="votes", cascade={"persist"})
* @ORM\JoinColumn(nullable=false) * @ORM\JoinColumn(nullable=false)
* @Serializer\Type("App\Entity\Poll")
*/ */
private $poll; private $poll;
/** /**