1
0
mirror of https://framagit.org/tykayn/date-poll-api synced 2023-08-25 08:23:11 +02:00

Compare commits

..

No commits in common. "747ebb9d2fdcf005ea47f66ce43b1eaac7c93b2c" and "1d72bfe68410438119f41be9bf4a38f3e8bf6cd7" have entirely different histories.

30 changed files with 1354 additions and 1441 deletions

View File

@ -83,14 +83,14 @@ class AdminController extends EmailsController {
// TODO // TODO
// fetch old polls and store their properties in new poll objects // fetch old polls and store their properties in new poll objects
$foundPolls = []; $foundPolls = [];
$database_name = 'symfony'; $database_name = 'symfony';
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
$emPoll = $this->getDoctrine()->getRepository( Poll::class ); $emPoll = $this->getDoctrine()->getRepository( Poll::class );
return $this->json( [ return $this->json( [
'message' => 'migration done for: ' . count( $foundPolls ) . ' - this feature is not ready to work YET.', 'message' => 'migration done for: ' . count( $foundPolls ). ' - this feature is not ready to work YET.',
'data' => [ 'data' => [
'count' => count( $foundPolls ), 'count' => count( $foundPolls ),
], ],

View File

@ -2,9 +2,14 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\Owner;
use App\Entity\Poll; use App\Entity\Poll;
use App\Repository\PollRepository;
use App\Service\MailService;
use FOS\RestBundle\Controller\Annotations\Get; use FOS\RestBundle\Controller\Annotations\Get;
use FOS\RestBundle\Controller\Annotations\Route; use FOS\RestBundle\Controller\Annotations\Route;
use JMS\Serializer\Type\Exception\Exception;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface; use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
/** /**

View File

@ -5,10 +5,8 @@ namespace App\Controller;
use App\Entity\Owner; use App\Entity\Owner;
use App\Entity\Poll; use App\Entity\Poll;
use JMS\Serializer\Type\Exception\Exception; use JMS\Serializer\Type\Exception\Exception;
use Swift_Mailer;
use Swift_Message; use Swift_Message;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
/** /**
* sending emails controller * sending emails controller
@ -20,37 +18,16 @@ class EmailsController extends AbstractController {
private $mail_service; private $mail_service;
public function __construct( Swift_Mailer $mailer ) { public function __construct( \Swift_Mailer $mailer ) {
$this->mail_service = $mailer; $this->mail_service = $mailer;
} }
/**
* send created polls to an owner
*
* @param Owner $owner
*
* @return int|void
* @throws Exception
* @throws TransportExceptionInterface
*/
public function sendOwnerPollsAction( Owner $owner ) {
$config = [
'owner' => $owner,
'title' => $this->getParameter( 'WEBSITE_NAME' ) . ' | Mes sondages',
'email_template' => 'emails/owner-list.html.twig',
];
$this->sendMailWithVars( $config );
return 1;
}
/** /**
* generic way to send email with html template * generic way to send email with html template
* *
* @param $config * @param $config
* *
* @throws TransportExceptionInterface * @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
*/ */
public function sendMailWithVars( $config ) { public function sendMailWithVars( $config ) {
@ -80,7 +57,7 @@ class EmailsController extends AbstractController {
$config[ 'email_template' ], $config[ 'email_template' ],
$config $config
); );
$message = ( new Swift_Message( $config[ 'title' ] ) ) $message = ( new Swift_Message( $config[ 'title' ] ) )
->setContentType( "text/html" ) ->setContentType( "text/html" )
->setCharset( 'UTF-8' ) ->setCharset( 'UTF-8' )
->setFrom( [ 'ne-pas-repondre@framadate-api.cipherbliss.com' ] ) ->setFrom( [ 'ne-pas-repondre@framadate-api.cipherbliss.com' ] )
@ -95,11 +72,33 @@ class EmailsController extends AbstractController {
} }
/**
* send created polls to an owner
*
* @param Owner $owner
*
* @return int|void
* @throws Exception
* @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
*/
public function sendOwnerPollsAction( Owner $owner ) {
$config = [
'owner' => $owner,
'title' => $this->getParameter( 'WEBSITE_NAME' ) . ' | Mes sondages',
'email_template' => 'emails/owner-list.html.twig',
];
$this->sendMailWithVars( $config );
return 1;
}
/** /**
* @param Owner $foundOwner * @param Owner $foundOwner
* @param Poll|null $poll * @param Poll|null $poll
* *
* @throws TransportExceptionInterface * @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
*/ */
public function sendCreationMailAction( Owner $foundOwner, Poll $poll = null ) { public function sendCreationMailAction( Owner $foundOwner, Poll $poll = null ) {
@ -121,14 +120,14 @@ class EmailsController extends AbstractController {
* @param $comment * @param $comment
* *
* @return int * @return int
* @throws TransportExceptionInterface * @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
*/ */
public function sendCommentNotificationAction( Owner $owner, $comment ) { public function sendCommentNotificationAction( Owner $owner, $comment ) {
$config = [ $config = [
'owner' => $owner, 'owner' => $owner,
'comment' => $comment, 'comment' => $comment,
'poll' => $comment->getPoll(), 'poll' => $comment->getPoll(),
'title' => 'Framadate | Commentaire de "' . $owner->getPseudo() . '" - sondage ' . $comment->getPoll()->getTitle(), 'title' => 'Framadate | Commentaire de "' . $owner->getPseudo() . '" - sondage ' . $comment->getPoll()->getTitle(),
'email_template' => 'emails/comment-notification.html.twig', 'email_template' => 'emails/comment-notification.html.twig',
]; ];
@ -142,14 +141,14 @@ class EmailsController extends AbstractController {
* @param $stackOfVotes * @param $stackOfVotes
* *
* @return int * @return int
* @throws TransportExceptionInterface * @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
*/ */
public function sendVoteNotificationAction( Owner $owner, $stackOfVotes ) { public function sendVoteNotificationAction( Owner $owner, $stackOfVotes ) {
$config = [ $config = [
'owner' => $owner, 'owner' => $owner,
'comment' => $stackOfVotes, 'comment' => $stackOfVotes,
'poll' => $stackOfVotes->getPoll(), 'poll' => $stackOfVotes->getPoll(),
'title' => 'Framadate | Vote de "' . $owner->getPseudo() . '" - sondage ' . $stackOfVotes->getPoll()->getTitle(), 'title' => 'Framadate | Vote de "' . $owner->getPseudo() . '" - sondage ' . $stackOfVotes->getPoll()->getTitle(),
'email_template' => 'emails/vote-notification.html.twig', 'email_template' => 'emails/vote-notification.html.twig',
]; ];

View File

@ -1,19 +1,20 @@
<?php <?php
namespace App\Controller; namespace App\Controller;
//use FOS\RestBundle\Controller\Annotations\Get; //use FOS\RestBundle\Controller\Annotations\Get;
//use FOS\RestBundle\Controller\Annotations\Route; //use FOS\RestBundle\Controller\Annotations\Route;
use App\Entity\Choice; use App\Entity\Choice;
use App\Entity\Comment; use App\Entity\Comment;
use App\Entity\Owner;
use App\Entity\Poll;
use App\Entity\StackOfVotes; use App\Entity\StackOfVotes;
use App\Entity\Vote; use App\Entity\Vote;
use App\Repository\PollRepository;
use App\Service\MailService;
use FOS\RestBundle\Controller\Annotations\Get; use FOS\RestBundle\Controller\Annotations\Get;
use FOS\RestBundle\Controller\Annotations\Route; use FOS\RestBundle\Controller\Annotations\Route;
use PDO; use JMS\Serializer\Type\Exception\Exception;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use App\Entity\Owner;
use App\Entity\Poll;
/** /**
* Class DefaultController * Class DefaultController
@ -33,40 +34,40 @@ class MigrationController extends EmailsController {
return new JsonResponse( [ return new JsonResponse( [
'error' => 'NOPE! veuillez vérifier votre fichier .env', 'error' => 'NOPE! veuillez vérifier votre fichier .env',
] ); ] );
} };
// fetch old Database // fetch old Database
$debug = ''; $debug = '';
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
$pollsBySlug = []; $pollsBySlug = [];
$pdo_options[ PDO::ATTR_ERRMODE ] = PDO::ERRMODE_EXCEPTION; $pdo_options[ \PDO::ATTR_ERRMODE ] = \PDO::ERRMODE_EXCEPTION;
$bdd = new PDO( 'mysql:host=localhost;dbname=' . $this->getParameter( 'OLD_DATABASE_NAME' ), $bdd = new \PDO( 'mysql:host=localhost;dbname=' . $this->getParameter( 'OLD_DATABASE_NAME' ),
$this->getParameter( 'OLD_DATABASE_USER' ), $this->getParameter( 'OLD_DATABASE_USER' ),
$this->getParameter( 'OLD_DATABASE_PASS' ), $this->getParameter( 'OLD_DATABASE_PASS' ),
$pdo_options ); $pdo_options );
$res_polls = $bdd->query( 'SELECT * FROM fd_poll' ); $res_polls = $bdd->query( 'SELECT * FROM fd_poll' );
while ( $d = $res_polls->fetch( PDO::FETCH_OBJ ) ) { while ( $d = $res_polls->fetch( \PDO::FETCH_OBJ ) ) {
$debug .= " <br> ajout de sondage : " . $d->title . ' - ' . $d->id; $debug .= " <br> ajout de sondage : ".$d->title .' - '. $d->id ;
$newPoll = new Poll(); $newPoll = new Poll();
$owner = new Owner(); $owner = new Owner();
$owner->setEmail( $d->admin_mail ) $owner->setEmail( $d->admin_mail )
->setPseudo( $d->admin_name ) ->setPseudo( $d->admin_name )
->addPoll( $newPoll ); ->addPoll($newPoll);
$newPoll $newPoll
->setOwner( $owner ) ->setOwner( $owner )
->setCustomURL( $d->id ) ->setCustomURL( $d->id )
->setKind( $d->id === 'D' ? 'date' : 'text' ) ->setKind( $d->id === 'D' ? 'date' : 'text' )
->setHideResults( ! $d->results_publicly_visible ) ->setHideResults( ! $d->results_publicly_visible )
->setAdminKey( $d->admin_id ) ->setAdminKey( $d->admin_id )
->setTitle( $d->title ) ->setTitle( $d->title )
->setVotesAllowed( $d->receiveNewVotes ) ->setVotesAllowed( $d->receiveNewVotes )
@ -74,7 +75,7 @@ class MigrationController extends EmailsController {
->setChoicesMax( $d->ValueMax ) ->setChoicesMax( $d->ValueMax )
->setPassword( $d->password_hash ) ->setPassword( $d->password_hash )
->setDescription( $d->description ) ->setDescription( $d->description )
->setCreatedAt( date_create( $d->creation_date ) ); ->setCreationDate( date_create( $d->creation_date ) );
$pollsBySlug[ $d->id ] = $newPoll; $pollsBySlug[ $d->id ] = $newPoll;
@ -83,102 +84,105 @@ class MigrationController extends EmailsController {
$em->persist( $newPoll ); $em->persist( $newPoll );
} }
// get choices, slots and link them with poll by their slug // get choices, slots and link them with poll by their slug
$res_slots = $bdd->query( 'SELECT * FROM fd_slot' ); $res_slots = $bdd->query( 'SELECT * FROM fd_slot' );
$pollChoicesOrderedBySlug = []; $pollChoicesOrderedBySlug = [];
$choicesCreated = []; $choicesCreated = [];
while ( $d = $res_slots->fetch( PDO::FETCH_OBJ ) ) { while ( $d = $res_slots->fetch( \PDO::FETCH_OBJ ) ) {
$debug .= " <br> ajout de slot, converti en choix de réponse : " . $d->poll_id . ' : ' . $d->moments; $debug .= " <br> ajout de slot, converti en choix de réponse : ".$d->poll_id. ' : '. $d->moments;
$pollSlug = $d->poll_id; $pollSlug = $d->poll_id;
$poll = $pollsBySlug[ $pollSlug ]; $poll = $pollsBySlug[$pollSlug];
$moments = explode( ',', $d->moments ); $moments = explode(',' , $d->moments);
foreach ( $moments as $moment ) { foreach ( $moments as $moment ) {
$newChoice = new Choice(); $newChoice = new Choice();
$newChoice $newChoice
->setPoll( $poll ) ->setPoll($poll)
->setDateTime( date_create( strtotime( $d->title ) ) ) ->setDateTime(date_create( strtotime( $d->title)))
->setName( $moment ); ->setName($moment);
$pollChoicesOrderedBySlug[ $pollSlug ][] = $newChoice; $pollChoicesOrderedBySlug[$pollSlug][] = $newChoice;
$poll->addChoice( $newChoice ); $poll->addChoice($newChoice);
$em->persist( $newChoice ); $em->persist( $newChoice );
$em->persist( $newPoll ); $em->persist( $newPoll );
$choicesCreated[] = $newChoice; $choicesCreated[] = $newChoice;
} }
} }
// get votes // get votes
$stacksOfVote = []; $stacksOfVote = [];
$res_votes = $bdd->query( 'SELECT * FROM fd_vote' ); $res_votes = $bdd->query( 'SELECT * FROM fd_vote' );
while ( $d = $res_votes->fetch( PDO::FETCH_OBJ ) ) { while ( $d = $res_votes->fetch( \PDO::FETCH_OBJ ) ) {
$debug .= " <br> ajout de stack de vote : " . $d->name; $debug .= " <br> ajout de stack de vote : ".$d->name;
$pollSlug = $d->poll_id; $pollSlug = $d->poll_id;
$poll = $pollsBySlug[ $pollSlug ]; $poll = $pollsBySlug[ $pollSlug ];
$newStack = new StackOfVotes(); $newStack = new StackOfVotes();
$newOwner = new Owner(); $newOwner = new Owner();
$newOwner $newOwner
->setPseudo( $d->name ) ->setPseudo($d->name)
->setEmail( 'the_anonymous_email_from_@_migration_offramadate.org' ) ->setEmail('the_anonymous_email_from_@_migration_offramadate.org')
->setModifierToken( $d->uniqId ); ->setModifierToken($d->uniqId)
;
$newStack->setPoll( $poll ) $newStack->setPoll($poll)
->setOwner( $newOwner ) ->setOwner($newOwner)
->setPseudo( $d->name ); ->setPseudo($d->name)
;
// each choice answer is encoded in a value : // each choice answer is encoded in a value :
$voteCodes = str_split( $d->choices ); $voteCodes = str_split($d->choices);
// get choices of the poll and answer accordingly // get choices of the poll and answer accordingly
$ii = 0; $ii=0;
foreach ( $voteCodes as $vote_code ) { foreach ( $voteCodes as $vote_code ) {
if ( $vote_code !== ' ' ) { if($vote_code !== ' '){
$choice = $pollChoicesOrderedBySlug[ $pollSlug ][ $ii ]; $choice = $pollChoicesOrderedBySlug[$pollSlug][$ii];
$newVote = new Vote(); $newVote = new Vote();
$newVote $newVote
->setChoice( $choice ) ->setChoice($choice)
->setStacksOfVotes( $newStack ) ->setStacksOfVotes($newStack)
->setPoll( $poll ) ->setPoll($poll)
->setValue( $this->mapAnswerNumberToWord( $vote_code ) ); ->setValue( $this->mapAnswerNumberToWord($vote_code))
$newStack->addVote( $newVote ); ;
$newStack->addVote($newVote);
$em->persist( $newVote ); $em->persist( $newVote );
$votes[] = $newVote; $votes[] = $newVote;
} }
$ii ++; $ii++;
} }
$poll->addStackOfVote( $newStack ); $poll->addStackOfVote($newStack);
$em->persist( $newStack ); $em->persist( $newStack );
$stacksOfVote[] = $newStack; $stacksOfVote[] = $newStack;
} }
$comments = []; $comments = [];
$res_comments = $bdd->query( 'SELECT * FROM fd_comment' ); $res_comments = $bdd->query( 'SELECT * FROM fd_comment' );
while ( $d = $res_comments->fetch( PDO::FETCH_OBJ ) ) { while ( $d = $res_comments->fetch( \PDO::FETCH_OBJ ) ) {
$debug .= " <br> ajout de commentaire : " . $d->name . ' ' . $d->comment; $debug .= " <br> ajout de commentaire : ".$d->name. ' '. $d->comment;
$pollSlug = $d->poll_id; $pollSlug = $d->poll_id;
$poll = $pollsBySlug[ $pollSlug ]; $poll = $pollsBySlug[ $pollSlug ];
$newComment = new Comment(); $newComment = new Comment();
$poll->addComment( $newComment ); $poll->addComment($newComment);
$newComment->setPoll( $poll ) $newComment->setPoll($poll)
->setCreatedAt( date_create( $d->date ) ) ->setCreatedAt( date_create($d->date))
->setText( $d->comment ) ->setText( $d->comment)
// TODO update entities // TODO update entities
->setPseudo( $d->name ); ->setPseudo( $d->name);
$em->persist( $newComment ); $em->persist( $newComment );
$comments[] = $newComment; $comments[] = $newComment;
@ -190,45 +194,41 @@ class MigrationController extends EmailsController {
// failure notice // failure notice
$debug .= " <br> <br> ça c'est fait. "; $debug .= " <br> <br> ça c'est fait. ";
return $this->render( 'pages/migration.html.twig', return $this->render('pages/migration.html.twig' , [
[ "message" => "welcome to the framadate migration endpoint, it has yet to be done",
"message" => "welcome to the framadate migration endpoint, it has yet to be done", "debug" => $debug,
"debug" => $debug, "OLD_DATABASE_NAME" => $this->getParameter( 'OLD_DATABASE_NAME' ),
"OLD_DATABASE_NAME" => $this->getParameter( 'OLD_DATABASE_NAME' ), "OLD_DATABASE_USER" => $this->getParameter( 'OLD_DATABASE_USER' ),
"OLD_DATABASE_USER" => $this->getParameter( 'OLD_DATABASE_USER' ), "counters" =>[
"counters" => [ 'polls' => count($pollsBySlug),
'polls' => count( $pollsBySlug ), 'comments' => count($comments),
'comments' => count( $comments ), 'choices' => count($choicesCreated),
'choices' => count( $choicesCreated ), 'stacks_of_votes' => count($stacksOfVote),
'stacks_of_votes' => count( $stacksOfVote ), 'votes' => count($votes),
'votes' => count( $votes ), ]
], ]);
] );
} }
/** /**
* @param $numberToConvert * @param $numberToConvert
* conversion of answer: * conversion of answer:
* space character : no answer, 0 : no , 1 : maybe , 2 : yes * space character : no answer, 0 : no , 1 : maybe , 2 : yes
*
* @return string * @return string
*/ */
public function mapAnswerNumberToWord( $numberToConvert ) { public function mapAnswerNumberToWord($numberToConvert){
$word = ''; $word = '';
switch ( $numberToConvert ) { switch ($numberToConvert){
case 0: case 0:
$word = 'no'; $word = 'no';
break; break;
case 1: case 1:
$word = 'maybe'; $word = 'maybe';
break; break;
case 2: case 2:
$word = 'yes'; $word = 'yes';
break; break;
default: default:
$word = 'no'; $word = 'no';
} }
return $word; return $word;
} }

View File

@ -9,103 +9,104 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
/** /**
* @Route("/poll") * @Route("/poll")
*/ */
class PollController extends AbstractController { class PollController extends AbstractController
/** {
* @Route("/", name="poll_index", methods={"GET"}) /**
*/ * @Route("/", name="poll_index", methods={"GET"})
public function index( PollRepository $pollRepository ): Response { */
public function index(PollRepository $pollRepository): Response
{
$polls = $pollRepository->findAll(); $polls = $pollRepository->findAll();
$titles = []; $titles=[];
foreach ( $polls as $poll ) { foreach ( $polls as $poll ) {
$titles[] = $poll->getTitle(); $titles[] = $poll->getTitle();
} }
return $this->render('poll/index.html.twig', [
'count' => count($polls),
'titles' => $titles,
'polls' => $polls,
]);
}
return $this->render( 'poll/index.html.twig', /**
[ * @Route("/new", name="poll_new", methods={"GET","POST"})
'count' => count( $polls ), */
'titles' => $titles, public function new(Request $request): Response
'polls' => $polls, {
] ); $poll = new Poll();
} $form = $this->createForm(PollType::class, $poll);
$form->handleRequest($request);
/** if ($form->isSubmitted() && $form->isValid()) {
* @Route("/new", name="poll_new", methods={"GET","POST"}) $entityManager = $this->getDoctrine()->getManager();
*/ $entityManager->persist($poll);
public function new( Request $request ): Response { $entityManager->flush();
$poll = new Poll();
$form = $this->createForm( PollType::class, $poll );
$form->handleRequest( $request );
if ( $form->isSubmitted() && $form->isValid() ) { return $this->redirectToRoute('poll_index');
$entityManager = $this->getDoctrine()->getManager(); }
$entityManager->persist( $poll );
$entityManager->flush();
return $this->redirectToRoute( 'poll_index' ); return $this->render('poll/new.html.twig', [
} 'poll' => $poll,
'form' => $form->createView(),
]);
}
return $this->render( 'poll/new.html.twig', /**
[ * on cherche un sondage par son url personnalisée
'poll' => $poll, * @Route("/{id}", name="poll_show", methods={"GET"})
'form' => $form->createView(), */
] ); public function show($id): Response
} {
$repository = $this->getDoctrine()->getRepository(Poll::class);
$foundPoll = $repository->findOneByCustomUrl($id);
if(!$foundPoll){
return $this->json([
'message' => $id.' : not found'
], 404);
}
/** return $this->render('poll/show.html.twig', [
* on cherche un sondage par son url personnalisée 'poll' => $foundPoll,
* @Route("/{id}", name="poll_show", methods={"GET"}) ]);
*/ }
public function show( $id ): Response {
$repository = $this->getDoctrine()->getRepository( Poll::class );
$foundPoll = $repository->findOneByCustomUrl( $id );
if ( ! $foundPoll ) {
return $this->json( [
'message' => $id . ' : not found',
],
404 );
}
return $this->render( 'poll/show.html.twig', /**
[ * @Route("/{id}/edit", name="poll_edit", methods={"GET","POST"})
'poll' => $foundPoll, */
] ); public function edit(Request $request, Poll $poll): Response
} {
$form = $this->createForm(PollType::class, $poll);
$form->handleRequest($request);
/** if ($form->isSubmitted() && $form->isValid()) {
* @Route("/{id}/edit", name="poll_edit", methods={"GET","POST"}) $this->getDoctrine()->getManager()->flush();
*/
public function edit( Request $request, Poll $poll ): Response {
$form = $this->createForm( PollType::class, $poll );
$form->handleRequest( $request );
if ( $form->isSubmitted() && $form->isValid() ) { return $this->redirectToRoute('poll_index');
$this->getDoctrine()->getManager()->flush(); }
return $this->redirectToRoute( 'poll_index' ); return $this->render('poll/edit.html.twig', [
} 'poll' => $poll,
'form' => $form->createView(),
]);
}
return $this->render( 'poll/edit.html.twig', /**
[ * @Route("/{id}", name="poll_delete", methods={"DELETE"})
'poll' => $poll, */
'form' => $form->createView(), public function delete(Request $request, Poll $poll): Response
] ); {
} if ($this->isCsrfTokenValid('delete'.$poll->getId(), $request->request->get('_token'))) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->remove($poll);
$entityManager->flush();
}
/** return $this->redirectToRoute('poll_index');
* @Route("/{id}", name="poll_delete", methods={"DELETE"}) }
*/
public function delete( Request $request, Poll $poll ): Response {
if ( $this->isCsrfTokenValid( 'delete' . $poll->getId(), $request->request->get( '_token' ) ) ) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->remove( $poll );
$entityManager->flush();
}
return $this->redirectToRoute( 'poll_index' );
}
} }

View File

@ -36,15 +36,13 @@ class CommentController extends EmailsController {
SerializerInterface $serializer, SerializerInterface $serializer,
Poll $poll Poll $poll
) { ) {
$jsonResponse = $serializer->serialize( [ $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');
],
'json' );
$response = new Response( $jsonResponse ); $response = new Response($jsonResponse);
$response->headers->set( 'Content-Type', 'application/json' ); $response->headers->set('Content-Type', 'application/json');
$response->setStatusCode( 200 ); $response->setStatusCode(200);
return $response; return $response;
@ -74,8 +72,8 @@ class CommentController extends EmailsController {
$em = $this->getDoctrine()->getRepository( Owner::class ); $em = $this->getDoctrine()->getRepository( Owner::class );
$data = json_decode( $data, true ); $data = json_decode( $data, true );
if ( ! isset( $data[ 'email' ] ) ) { if(!isset($data['email'])) {
return $this->json( [ "message" => "Incorrect JSON in request" ], 400 ); return $this->json(["message" => "Incorrect JSON in request"], 400);
} }
$foundOwner = $em->findOneByEmail( $data[ 'email' ] ); $foundOwner = $em->findOneByEmail( $data[ 'email' ] );
@ -83,8 +81,8 @@ class CommentController extends EmailsController {
if ( ! $foundOwner ) { if ( ! $foundOwner ) {
$foundOwner = new Owner(); $foundOwner = new Owner();
$foundOwner->setPseudo( $data[ 'email' ] ) $foundOwner->setPseudo( $data[ 'email' ] )
->setEmail( $data[ 'email' ] ) ->setEmail( $data[ 'email' ] )
->setModifierToken( uniqid( '', true ) ); ->setModifierToken( uniqid( '', true ) );
} }
// anti flood // anti flood
$seconds_limit_lastpost = 5; $seconds_limit_lastpost = 5;
@ -120,8 +118,8 @@ class CommentController extends EmailsController {
} }
} }
$comment->setOwner( $foundOwner ) $comment->setOwner( $foundOwner )
->setCreatedAt( new DateTime() ) ->setCreatedAt( new DateTime() )
->setPoll( $poll ); ->setPoll( $poll );
$foundOwner->addComment( $comment ); $foundOwner->addComment( $comment );
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
@ -129,8 +127,8 @@ class CommentController extends EmailsController {
$em->persist( $comment ); $em->persist( $comment );
$em->flush(); $em->flush();
if ( $poll->getMailOnComment() ) { if($poll->getMailOnComment()){
$this->sendCommentNotificationAction( $foundOwner, $comment ); $this->sendCommentNotificationAction($foundOwner, $comment);
} }

View File

@ -7,11 +7,6 @@ use App\Entity\Choice;
use App\Entity\Owner; use App\Entity\Owner;
use App\Entity\Poll; use App\Entity\Poll;
use App\Repository\PollRepository; use App\Repository\PollRepository;
use FOS\RestBundle\Controller\Annotations\Delete;
use FOS\RestBundle\Controller\Annotations\Get;
use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\Put;
use FOS\RestBundle\Controller\Annotations\Route;
use JMS\Serializer\Exception\RuntimeException; use JMS\Serializer\Exception\RuntimeException;
use JMS\Serializer\SerializerBuilder; use JMS\Serializer\SerializerBuilder;
use JMS\Serializer\SerializerInterface; use JMS\Serializer\SerializerInterface;
@ -19,6 +14,13 @@ 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; use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use FOS\RestBundle\Controller\Annotations\Get;
use FOS\RestBundle\Controller\Annotations\Put;
use FOS\RestBundle\Controller\Annotations\Delete;
use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\Route;
/** /**
* Class DefaultController * Class DefaultController
@ -61,6 +63,19 @@ class PollController extends EmailsController {
} }
/**
* @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 a poll config by its custom URL, we do not want polls to be reachable by their numeric id
* @Get( * @Get(
@ -88,9 +103,30 @@ class PollController extends EmailsController {
$comments = $poll->getComments(); $comments = $poll->getComments();
$stacks = $poll->getStacksOfVotes(); $stacks = $poll->getStacksOfVotes();
$displayedComments = [];
foreach ( $comments as $comment ) {
$displayedComments[] = $comment->display();
}
$displayedStackOfVotes = [];
foreach ( $stacks as $stack ) {
$displayedStackOfVotes[] = $stack->display();
}
$displayedChoices = [];
foreach ( $poll->getChoices() as $choice
) {
$displayedChoices[] = $choice->display();
}
$pass = $poll->getPassword(); $pass = $poll->getPassword();
$returnedPoll = [
'message' => 'your poll config for ' . $poll->getTitle(),
'poll' => $poll->display(),
// TODO do not render sub objects of owner, it returns too many thing
'stacks' => $displayedStackOfVotes,
'choices' => $displayedChoices,
'comments' => $displayedComments,
];
/** /**
* password protected content * password protected content
@ -104,24 +140,13 @@ class PollController extends EmailsController {
} else { } else {
// free access to poll // free access to poll
return $this->json( $poll->display() ); // return $this->returnPollData( $poll, $serializer );
return $this->json( $returnedPoll );
// return $this->json($poll);
} }
} }
/**
* @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 a poll config by its custom URL, we do not want polls to be reachable by their numeric id
* @Get( * @Get(
@ -142,9 +167,9 @@ class PollController extends EmailsController {
return $this->notFoundPoll( $customUrl ); return $this->notFoundPoll( $customUrl );
} }
if ( md5( $poll->getPassword() ) === $md5 ) { if ( $poll->getPassword() === $md5 ) {
// good matching pass // good matching pass
return $this->json( $poll->display() ); return $this->returnPollData( $poll, $serializer );
} else { } else {
// wrong pass // wrong pass
return $this->json( [ return $this->json( [
@ -193,8 +218,10 @@ class PollController extends EmailsController {
$em->persist( $poll ); $em->persist( $poll );
$em->flush(); $em->flush();
return $this->json( $poll->displayForAdmin() return $this->json( [
, 'message' => 'you updated the poll ' . $poll->getTitle(),
"poll" => $poll,
],
200 ); 200 );
} }
@ -276,6 +303,7 @@ class PollController extends EmailsController {
$newChoice = new Choice(); $newChoice = new Choice();
$newChoice $newChoice
->setPoll( $newpoll ) ->setPoll( $newpoll )
// ->setUrl( $c[ 'url' ] )
->setName( $c[ 'literal' ] ); ->setName( $c[ 'literal' ] );
$em->persist( $newChoice ); $em->persist( $newChoice );
// TODO add also choices for each time range in a day // TODO add also choices for each time range in a day
@ -302,9 +330,11 @@ class PollController extends EmailsController {
$this->sendCreationMailAction( $foundOwner, $newpoll ); $this->sendCreationMailAction( $foundOwner, $newpoll );
return $this->json( [ return $this->json( [
'message' => 'you created a poll ' . $precision, 'message' => 'you created a poll ' . $precision,
'poll' => $newpoll->displayForAdmin, 'poll' => $newpoll,
'password_protected' => is_string( $newpoll->getPassword() ), 'password_protected' => is_string( $newpoll->getPassword() ),
'admin_key' => $newpoll->getAdminKey(),
'owner_modifier_token' => $foundOwner->getModifierToken(),
], ],
201 ); 201 );

View File

@ -31,7 +31,6 @@ class VoteController extends EmailsController {
* name = "new_vote_stack", * name = "new_vote_stack",
* requirements = {"content"="\w+", "poll_id"="\d+"} * requirements = {"content"="\w+", "poll_id"="\d+"}
* ) * )
*
* @param SerializerInterface $serializer * @param SerializerInterface $serializer
* @param Poll $poll * @param Poll $poll
* @param Request $request * @param Request $request
@ -67,11 +66,10 @@ class VoteController extends EmailsController {
} }
// TODO anti flood // TODO anti flood
$foundOwner $foundOwner
->setModifierToken( $poll->generateRandomKey() ); ->setModifierToken( $poll->generateAdminKey() );
$stack = new StackOfVotes(); $stack = new StackOfVotes();
$stack $stack
->setOwner( $foundOwner ) ->setOwner( $foundOwner )
->setIp( $_SERVER[ 'REMOTE_ADDR' ] )
->setPseudo( $data[ 'pseudo' ] ) ->setPseudo( $data[ 'pseudo' ] )
->setPoll( $poll ); ->setPoll( $poll );
foreach ( $data[ 'votes' ] as $voteInfo ) { foreach ( $data[ 'votes' ] as $voteInfo ) {
@ -98,8 +96,8 @@ class VoteController extends EmailsController {
404 ); 404 );
} }
$vote->setPoll( $poll ) $vote->setPoll( $poll )
->setChoice( $foundChoice ) ->setChoice( $foundChoice )
->setValue( $voteInfo[ 'value' ] ); ->setValue( $voteInfo[ 'value' ] );
$vote->setPoll( $poll ); $vote->setPoll( $poll );
$stack->addVote( $vote ); $stack->addVote( $vote );
$poll->addVote( $vote ); $poll->addVote( $vote );
@ -118,17 +116,17 @@ class VoteController extends EmailsController {
} }
$stacks = $poll->getStacksOfVotes(); $stacks = $poll->getStacksOfVotes();
if ( $poll->getMailOnVote() ) { if($poll->getMailOnVote()){
$this->sendVoteNotificationAction( $stack->getOwner(), $stack ); $this->sendVoteNotificationAction($stack->getOwner(), $stack);
} }
$returnedVoteStack = $stack; $returnedVoteStack = $stack;
$jsonResponse = $serializer->serialize( $returnedVoteStack, 'json' ); $jsonResponse = $serializer->serialize($returnedVoteStack, 'json');
$response = new Response( $jsonResponse ); $response = new Response($jsonResponse);
$response->headers->set( 'Content-Type', 'application/json' ); $response->headers->set('Content-Type', 'application/json');
$response->setStatusCode( 200 ); $response->setStatusCode(200);
return $response; return $response;
@ -141,7 +139,6 @@ class VoteController extends EmailsController {
* name = "update_vote_stack", * name = "update_vote_stack",
* requirements = { "id"="\d+"} * requirements = { "id"="\d+"}
* ) * )
*
* @param SerializerInterface $serializer * @param SerializerInterface $serializer
* @param StackOfVotes $id * @param StackOfVotes $id
* @param $modifierToken * @param $modifierToken
@ -174,16 +171,15 @@ class VoteController extends EmailsController {
// save evrything // save evrything
$jsonResponse = $serializer->serialize( [ $jsonResponse = $serializer->serialize([
'message' => 'ok', 'message' => 'ok',
'modifier_token' => $voteStack->getOwner()->getModifierToken(), 'modifier_token' => $voteStack->getOwner()->getModifierToken(),
'vote_stack' => $voteStack, 'vote_stack' => $voteStack,
], ], 'json');
'json' );
$response = new Response( $jsonResponse ); $response = new Response($jsonResponse);
$response->headers->set( 'Content-Type', 'application/json' ); $response->headers->set('Content-Type', 'application/json');
$response->setStatusCode( 200 ); $response->setStatusCode(200);
return $response; return $response;
@ -211,13 +207,11 @@ class VoteController extends EmailsController {
return $this->json( [ return $this->json( [
'message' => 'boom! les ' . $length . ' votes du sondage ont été supprimés', 'message' => 'boom! les ' . $length . ' votes du sondage ont été supprimés',
], ],200 );
200 );
} else { } else {
return $this->json( [ return $this->json( [
'message' => 'le token d\'autorisation est invalide, vous ne pouvez pas modifier ce sondage', 'message' => 'le token d\'autorisation est invalide, vous ne pouvez pas modifier ce sondage'
], ],403 );
403 );
} }
} }
} }

View File

@ -6,11 +6,13 @@ use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectManager;
class AppFixtures extends Fixture { class AppFixtures extends Fixture
public function load( ObjectManager $manager ) { {
// $product = new Product(); public function load(ObjectManager $manager)
// $manager->persist($product); {
// $product = new Product();
// $manager->persist($product);
$manager->flush(); $manager->flush();
} }
} }

View File

@ -42,12 +42,12 @@ class AppPollFixtures extends Fixture {
$pollCitronOrange = new Poll(); $pollCitronOrange = new Poll();
$pollCitronOrange->setTitle( 'citron ou orange' ) $pollCitronOrange->setTitle( 'citron ou orange' )
->setCustomUrl( 'citron' ) ->setCustomUrl('citron')
->setDescription( 'votre sorbert préféré' ) ->setDescription( 'votre sorbert préféré' )
->setModificationPolicy( 'nobody' ) ->setModificationPolicy( 'nobody' )
->setPassword( 'le pass woute woute' ); ->setPassword('le pass woute woute');
$this->addReference( self::POLL_FIXTURE_ONE, $pollCitronOrange ); $this->addReference(self::POLL_FIXTURE_ONE, $pollCitronOrange);
$pollCitronOrange->setMailOnVote( true ); $pollCitronOrange->setMailOnVote( true );
$pollCitronOrange->setOwner( $owner ); $pollCitronOrange->setOwner( $owner );
@ -106,21 +106,21 @@ class AppPollFixtures extends Fixture {
$ownerComment = new Comment(); $ownerComment = new Comment();
$ownerComment $ownerComment
->setText( "trop bien ce sondage wohooo! signé l'auteur." ) ->setText( "trop bien ce sondage wohooo! signé l'auteur." )
->setPseudo( 'un gens qui commente' ) ->setPseudo('un gens qui commente')
->setOwner( $owner ); ->setOwner( $owner );
$pollCitronOrange->addComment( $ownerComment ); $pollCitronOrange->addComment( $ownerComment );
$someoneComment = new Comment(); $someoneComment = new Comment();
$someoneComment $someoneComment
->setText( "comme l'auteur se la raconte. PFFFF!" ) ->setText( "comme l'auteur se la raconte. PFFFF!" )
->setPseudo( 'un gens qui commente' ) ->setPseudo('un gens qui commente')
->setOwner( $commenterMan ); ->setOwner( $commenterMan );
$pollCitronOrange->addComment( $someoneComment ); $pollCitronOrange->addComment( $someoneComment );
$pollCitronOrange->setTitle( 'démo sondage de texte avec deux commentaires' ) $pollCitronOrange->setTitle( 'démo sondage de texte avec deux commentaires' )
->setCustomUrl( 'demo' ) ->setCustomUrl('demo')
->setDescription( 'description du sondage 2' ); ->setDescription( 'description du sondage 2' );
$pollCitronOrange->setModificationPolicy( 'self' ); $pollCitronOrange->setModificationPolicy( 'self' );
$pollCitronOrange->setMailOnComment( true ); $pollCitronOrange->setMailOnComment( true );
@ -138,9 +138,9 @@ class AppPollFixtures extends Fixture {
// voting test with 2 people // voting test with 2 people
// poll with date type // poll with date type
$pollCitronOrange = new Poll(); $pollCitronOrange = new Poll();
$choice = new Choice(); $choice = new Choice();
$firstDate = new DateTime(); $firstDate = new DateTime();
$choice->setName( $firstDate->format( 'Y-m-d H:i:s' ) ); $choice->setName( $firstDate->format( 'Y-m-d H:i:s' ) );
$choice2 = new Choice(); $choice2 = new Choice();
$choice3 = new Choice(); $choice3 = new Choice();
@ -148,42 +148,42 @@ class AppPollFixtures extends Fixture {
$choice3->setName( $pollCitronOrange->addDaysToDate( $firstDate, 2 )->format( 'Y-m-d H:i:s' ) ); $choice3->setName( $pollCitronOrange->addDaysToDate( $firstDate, 2 )->format( 'Y-m-d H:i:s' ) );
$pollCitronOrange->setTitle( "c'est pour aujourdhui ou pour demain" ) $pollCitronOrange->setTitle( "c'est pour aujourdhui ou pour demain" )
->setCustomUrl( 'aujourdhui-ou-demain' ) ->setCustomUrl('aujourdhui-ou-demain')
->setDescription( 'Vous avez le choix dans la date' ) ->setDescription( 'Vous avez le choix dans la date' )
->setKind( 'date' ) ->setKind( 'date' )
->setOwner( $owner ) ->setOwner( $owner )
->addChoice( $choice ) ->addChoice( $choice )
->addChoice( $choice2 ) ->addChoice( $choice2 )
->addChoice( $choice3 ) ->addChoice( $choice3 )
->setModificationPolicy( 'everybody' ); ->setModificationPolicy( 'everybody' );
$manager->persist( $pollCitronOrange ); $manager->persist( $pollCitronOrange );
// poll with cartoon choices // poll with cartoon choices
$pollCartoons = new Poll(); $pollCartoons = new Poll();
$pollCartoons->setTitle( 'dessin animé préféré' ) $pollCartoons->setTitle( 'dessin animé préféré' )
->setCustomUrl( 'dessin-anime' ) ->setCustomUrl('dessin-anime')
->setDescription( 'choisissez votre animé préféré' ) ->setDescription( 'choisissez votre animé préféré' )
->setOwner( $owner ) ->setOwner( $owner )
->setModificationPolicy( 'nobody' ) ->setModificationPolicy( 'nobody' )
->addTextChoiceArray( [ ->addTextChoiceArray( [
"Vic le viking", "Vic le viking",
"Boumbo petite automobile", "Boumbo petite automobile",
"Les mystérieuses cités d'or", "Les mystérieuses cités d'or",
"Les mondes engloutis", "Les mondes engloutis",
"Foot 2 rue", "Foot 2 rue",
"Le chat, la vache, et l'océan", "Le chat, la vache, et l'océan",
"Digimon", "Digimon",
] ); ] );
$someoneComment = new Comment(); $someoneComment = new Comment();
$someoneComment $someoneComment
->setPseudo( 'un gens qui commente' ) ->setPseudo('un gens qui commente')
->setText( "allez boumbo!" ) ->setText( "allez boumbo!" )
->setOwner( $commenterMan ); ->setOwner( $commenterMan );
$pollCartoons->addComment( $someoneComment ); $pollCartoons->addComment( $someoneComment );
$someoneComment2 = new Comment(); $someoneComment2 = new Comment();
$someoneComment2 $someoneComment2
->setPseudo( 'un gens qui commente' ) ->setPseudo('un gens qui commente')
->setText( "je suis pour la team rocket de digimon" ) ->setText( "je suis pour la team rocket de digimon" )
->setOwner( $owner ); ->setOwner( $owner );
$pollCartoons->addComment( $someoneComment2 ); $pollCartoons->addComment( $someoneComment2 );
@ -195,7 +195,7 @@ class AppPollFixtures extends Fixture {
$stack $stack
->setPoll( $pollCartoons ) ->setPoll( $pollCartoons )
->setOwner( $voter ); ->setOwner( $voter );
$pollCartoons->addStackOfVote( $stack ); $pollCartoons->addStackOfVote($stack);
$vote = new Vote(); $vote = new Vote();
$vote $vote
@ -203,7 +203,7 @@ class AppPollFixtures extends Fixture {
->setStacksOfVotes( $stack ) ->setStacksOfVotes( $stack )
->setValue( "yes" ) ->setValue( "yes" )
->setChoice( $pollCartoons->getChoices()[ 2 ] ); ->setChoice( $pollCartoons->getChoices()[ 2 ] );
$pollCartoons->addVote( $vote ); $pollCartoons->addVote($vote);
$vote = new Vote(); $vote = new Vote();
$vote $vote
@ -211,7 +211,7 @@ class AppPollFixtures extends Fixture {
->setStacksOfVotes( $stack ) ->setStacksOfVotes( $stack )
->setValue( "maybe" ) ->setValue( "maybe" )
->setChoice( $pollCartoons->getChoices()[ 1 ] ); ->setChoice( $pollCartoons->getChoices()[ 1 ] );
$pollCartoons->addVote( $vote ); $pollCartoons->addVote($vote);
$manager->persist( $stack ); $manager->persist( $stack );
@ -227,7 +227,7 @@ class AppPollFixtures extends Fixture {
->setStacksOfVotes( $stack ) ->setStacksOfVotes( $stack )
->setValue( "yes" ) ->setValue( "yes" )
->setChoice( $pollCartoons->getChoices()[ 1 ] ); ->setChoice( $pollCartoons->getChoices()[ 1 ] );
$pollCartoons->addVote( $vote ); $pollCartoons->addVote($vote);
$vote = new Vote(); $vote = new Vote();
$vote $vote
@ -235,7 +235,7 @@ class AppPollFixtures extends Fixture {
->setStacksOfVotes( $stack ) ->setStacksOfVotes( $stack )
->setValue( "yes" ) ->setValue( "yes" )
->setChoice( $pollCartoons->getChoices()[ 2 ] ); ->setChoice( $pollCartoons->getChoices()[ 2 ] );
$pollCartoons->addVote( $vote ); $pollCartoons->addVote($vote);
$vote = new Vote(); $vote = new Vote();
$vote $vote
@ -243,7 +243,7 @@ class AppPollFixtures extends Fixture {
->setStacksOfVotes( $stack ) ->setStacksOfVotes( $stack )
->setValue( "no" ) ->setValue( "no" )
->setChoice( $pollCartoons->getChoices()[ 2 ] ); ->setChoice( $pollCartoons->getChoices()[ 2 ] );
$pollCartoons->addVote( $vote ); $pollCartoons->addVote($vote);
$manager->persist( $pollCartoons ); $manager->persist( $pollCartoons );
$manager->persist( $stack ); $manager->persist( $stack );

View File

@ -3,14 +3,16 @@
namespace App\DataFixtures; namespace App\DataFixtures;
use App\Entity\Owner; use App\Entity\Owner;
use App\Entity\Poll;
use App\Entity\StackOfVotes; use App\Entity\StackOfVotes;
use App\Entity\Vote; use App\Entity\Vote;
use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface; use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectManager;
class VotesStacksFixtures extends Fixture implements DependentFixtureInterface { class VotesStacksFixtures extends Fixture implements DependentFixtureInterface {
public function getDependencies() { public function getDependencies()
{
return [ return [
AppPollFixtures::class, AppPollFixtures::class,
]; ];
@ -30,8 +32,8 @@ class VotesStacksFixtures extends Fixture implements DependentFixtureInterface {
// "citron ou orange" // "citron ou orange"
// add vote stacks on "citron ou orange" // add vote stacks on "citron ou orange"
$pollCitronOrange = $this->getReference( AppPollFixtures::POLL_FIXTURE_ONE ); $pollCitronOrange = $this->getReference(AppPollFixtures::POLL_FIXTURE_ONE);
$stack1 = new StackOfVotes(); $stack1 = new StackOfVotes();
$stack1 $stack1
->setPoll( $pollCitronOrange ) ->setPoll( $pollCitronOrange )
->setOwner( $people1 ); ->setOwner( $people1 );

View File

@ -1,151 +1,145 @@
<?php <?php
namespace App\Entity; namespace App\Entity;
use App\Traits\TimeStampableTrait; use DateTime;
use DateTime; use DateTimeInterface;
use DateTimeInterface; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping as ORM; use JMS\Serializer\Annotation as Serializer;
use JMS\Serializer\Annotation as Serializer;
/**
* one poll choice, could be a text or a date
* @ORM\Entity(repositoryClass="App\Repository\ChoiceRepository")
* @Serializer\ExclusionPolicy("all")
*/
class Choice {
use TimeStampableTrait;
/** /**
* @ORM\Id() * one poll choice, could be a text or a date
* @ORM\GeneratedValue() * @ORM\Entity(repositoryClass="App\Repository\ChoiceRepository")
* @ORM\Column(type="integer") * @Serializer\ExclusionPolicy("all")
* @Serializer\Expose()
*/ */
public $id; class Choice {
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Serializer\Expose()
*/
public $id;
/** /**
* @ORM\Column(type="string", length=255, nullable=true) * @ORM\Column(type="string", length=255, nullable=true)
* @Serializer\Type("string") * @Serializer\Type("string")
* @Serializer\Expose() * @Serializer\Expose()
*/ */
public $name; public $name;
/** /**
* @ORM\Column(type="string", length=1024, nullable=true) * @ORM\Column(type="string", length=1024, nullable=true)
* @Serializer\Type("string") * @Serializer\Type("string")
* @Serializer\Expose() * @Serializer\Expose()
*/ */
public $url; public $url;
/**
* @ORM\Column(type="datetime", nullable=true)
* @Serializer\Type("datetime")
*/
public $dateTime;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Vote", mappedBy="choice", cascade={"persist"})
* @Serializer\Type("App\Entity\Vote")
*/
public $votes;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="choices", cascade={"persist"})
* @Serializer\Type("App\Entity\Poll")
*/
private $poll;
/** public function __construct( $optionalName = null ) {
* @ORM\OneToMany(targetEntity="App\Entity\Vote", mappedBy="choice", cascade={"persist"}) $this->poll = new ArrayCollection();
* @Serializer\Type("App\Entity\Vote") $this->votes = new ArrayCollection();
*/ $this->setDateTime( new DateTime() );
public $votes; if ( $optionalName ) {
/** $this->setName( $optionalName );
* @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="choices", cascade={"persist"})
* @Serializer\Type("App\Entity\Poll")
*/
private $poll;
public function __construct( $optionalName = null ) {
$this->setCreatedAt( new DateTime() );
$this->poll = new ArrayCollection();
$this->votes = new ArrayCollection();
$this->setDateTime( new DateTime() );
if ( $optionalName ) {
$this->setName( $optionalName );
}
}
public function setDateTime( ?DateTimeInterface $dateTime ): self {
$this->dateTime = $dateTime;
return $this;
}
public function display( $kind = 'text' ) {
$fields = [
'id' => $this->getId(),
'created_at' => $this->getCreatedAtAsString(),
'name' => $this->getName(),
'url' => $this->getUrl(),
];
if ( $kind === 'date' ) {
$date = new DateTime( $this->getName() );
$fields[ 'name' ] = $date->format( 'c' );
}
return $fields;
}
public function getId(): ?int {
return $this->id;
}
public function getName(): ?string {
return $this->name;
}
public function setName( ?string $name ): self {
$this->name = $name;
return $this;
}
public function getUrl(): ?string {
return $this->url;
}
public function setUrl( ?string $url ): self {
$this->url = $url;
return $this;
}
public function getDateTime(): ?DateTimeInterface {
return $this->dateTime;
}
public function getPoll(): ?Poll {
return $this->poll;
}
public function setPoll( ?Poll $poll ): self {
$this->poll = $poll;
return $this;
}
/**
* @return Collection|Vote[]
*/
public function getVotes(): Collection {
return $this->votes;
}
public function addVote( Vote $vote ): self {
if ( ! $this->votes->contains( $vote ) ) {
$this->votes[] = $vote;
$vote->setChoice( $this );
}
return $this;
}
public function removeVote( Vote $vote ): self {
if ( $this->votes->contains( $vote ) ) {
$this->votes->removeElement( $vote );
// set the owning side to null (unless already changed)
if ( $vote->getChoice() === $this ) {
$vote->setChoice( null );
} }
} }
return $this;
public function display() {
return [
'id' => $this->getId(),
'date' => $this->getDateTime(),
'name' => $this->getName(),
'url' => $this->getUrl(),
];
}
public function getId(): ?int {
return $this->id;
}
public function getDateTime(): ?DateTimeInterface {
return $this->dateTime;
}
public function setDateTime( ?DateTimeInterface $dateTime ): self {
$this->dateTime = $dateTime;
return $this;
}
public function getName(): ?string {
return $this->name;
}
public function setName( ?string $name ): self {
$this->name = $name;
return $this;
}
public function getPoll(): ?Poll {
return $this->poll;
}
public function setPoll( ?Poll $poll ): self {
$this->poll = $poll;
return $this;
}
/**
* @return Collection|Vote[]
*/
public function getVotes(): Collection {
return $this->votes;
}
public function addVote( Vote $vote ): self {
if ( ! $this->votes->contains( $vote ) ) {
$this->votes[] = $vote;
$vote->setChoice( $this );
}
return $this;
}
public function removeVote( Vote $vote ): self {
if ( $this->votes->contains( $vote ) ) {
$this->votes->removeElement( $vote );
// set the owning side to null (unless already changed)
if ( $vote->getChoice() === $this ) {
$vote->setChoice( null );
}
}
return $this;
}
public function getUrl(): ?string {
return $this->url;
}
public function setUrl( ?string $url ): self {
$this->url = $url;
return $this;
}
} }
}

View File

@ -2,8 +2,6 @@
namespace App\Entity; namespace App\Entity;
use App\Traits\TimeStampableTrait;
use DateTime;
use DateTimeInterface; use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer; use JMS\Serializer\Annotation as Serializer;
@ -13,9 +11,6 @@ use JMS\Serializer\Annotation as Serializer;
* @Serializer\ExclusionPolicy("all") * @Serializer\ExclusionPolicy("all")
*/ */
class Comment { class Comment {
use TimeStampableTrait;
/** /**
* @ORM\Id() * @ORM\Id()
* @ORM\GeneratedValue() * @ORM\GeneratedValue()
@ -44,75 +39,84 @@ class Comment {
*/ */
private $text; private $text;
/**
* @ORM\Column(type="datetime")
* @Serializer\Type("datetime")
* @Serializer\Expose()
*/
private $createdAt;
/** /**
* @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="comments") * @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="comments")
*/ */
private $poll; private $poll;
function __construct() {
$this->setCreatedAt( new DateTime() );
}
public function setCreatedAt( DateTimeInterface $createdAt ): self {
$this->createdAt = $createdAt;
return $this;
}
public function getCreatedAt(): ?DateTimeInterface {
return $this->createdAt;
}
function display() { function display() {
return [ return [
'id' => $this->getId(), 'id' => $this->getId(),
'text' => $this->getText(), 'text' => $this->getText(),
'pseudo' => $this->getOwner()->getPseudo(), 'pseudo' => $this->getOwner()->getPseudo(),
'created_at' => $this->getCreatedAtAsString(), 'date' => $this->getCreatedAt(),
]; ];
} }
function __construct() {
$this->setCreatedAt( new \DateTime() );
}
public function getId(): ?int { public function getId(): ?int {
return $this->id; return $this->id;
} }
public function getText(): ?string {
return $this->text;
}
public function setText( string $text ): self {
$this->text = $text;
return $this;
}
public function getOwner(): ?Owner { public function getOwner(): ?Owner {
return $this->owner; return $this->owner;
} }
public function setOwner( ?Owner $owner ): self { public function setOwner( ?Owner $owner ): self {
$this->owner = $owner; $this->owner = $owner;
return $this;
}
return $this; public function getText(): ?string {
} return $this->text;
}
public function setText( string $text ): self {
$this->text = $text;
return $this;
}
public function getCreatedAt(): ?DateTimeInterface {
return $this->createdAt;
}
public function setCreatedAt( DateTimeInterface $createdAt ): self {
$this->createdAt = $createdAt;
return $this;
}
public function getPoll(): ?Poll { public function getPoll(): ?Poll {
return $this->poll; return $this->poll;
} }
public function setPoll( ?Poll $poll ): self { public function setPoll( ?Poll $poll ): self {
$this->poll = $poll; $this->poll = $poll;
return $this;
}
return $this; public function getPseudo(): ?string
} {
return $this->pseudo;
}
public function getPseudo(): ?string { public function setPseudo(string $pseudo): self
return $this->pseudo; {
} $this->pseudo = $pseudo;
public function setPseudo( string $pseudo ): self { return $this;
$this->pseudo = $pseudo; }
return $this;
}
} }

View File

@ -2,9 +2,6 @@
namespace App\Entity; namespace App\Entity;
use App\Traits\TimeStampableTrait;
use DateTime;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
@ -14,26 +11,24 @@ use JMS\Serializer\Annotation as Serializer;
* @ORM\Entity(repositoryClass="App\Repository\OwnerRepository") * @ORM\Entity(repositoryClass="App\Repository\OwnerRepository")
*/ */
class Owner { class Owner {
use TimeStampableTrait;
/** /**
* @ORM\Column(type="string", length=255) * @ORM\Column(type="string", length=255)
* @Serializer\Type("string") * @Serializer\Type("string")
* @Serializer\Expose() * @Serializer\Expose()
*/ */
public $pseudo; public $pseudo;
/**
* @ORM\Column(type="string", length=255)
* @Serializer\Type("string")
* @Serializer\Expose()
*/
public $email;
/** /**
* @ORM\Id() * @ORM\Id()
* @ORM\GeneratedValue() * @ORM\GeneratedValue()
* @ORM\Column(type="integer") * @ORM\Column(type="integer")
*/ */
private $id; private $id;
/**
* @ORM\Column(type="string", length=255)
* @Serializer\Type("string")
* @Serializer\Expose()
*/
public $email;
/** /**
* @ORM\OneToMany(targetEntity="App\Entity\Poll", mappedBy="owner",cascade={"persist","remove"},orphanRemoval=true) * @ORM\OneToMany(targetEntity="App\Entity\Poll", mappedBy="owner",cascade={"persist","remove"},orphanRemoval=true)
* @Serializer\Type("App\Entity\Poll") * @Serializer\Type("App\Entity\Poll")
@ -54,7 +49,10 @@ class Owner {
* @ORM\Column(type="string", length=255) * @ORM\Column(type="string", length=255)
*/ */
private $modifierToken; private $modifierToken;
/**
* @ORM\Column(type="datetime" , options={"default"="CURRENT_TIMESTAMP"})
*/
private $createdAt;
/** /**
* @ORM\Column(type="datetime" , options={"default"="CURRENT_TIMESTAMP"},nullable=true) * @ORM\Column(type="datetime" , options={"default"="CURRENT_TIMESTAMP"},nullable=true)
*/ */
@ -64,54 +62,10 @@ class Owner {
$this->polls = new ArrayCollection(); $this->polls = new ArrayCollection();
$this->comments = new ArrayCollection(); $this->comments = new ArrayCollection();
$this->stackOfVotes = new ArrayCollection(); $this->stackOfVotes = new ArrayCollection();
$this->setCreatedAt( new DateTime() ); $this->setCreatedAt( new \DateTime() );
$this->setModifierToken( uniqid() ); $this->setModifierToken( uniqid() );
$this->setCreatedAt( new DateTime() );
} }
public function setCreatedAt( DateTimeInterface $createdAt ): self {
$this->createdAt = $createdAt;
return $this;
}
public function getCreatedAt(): ?DateTimeInterface {
return $this->createdAt;
}
public function display() {
return [
'pseudo' => $this->getPseudo(),
];
}
public function getPseudo(): ?string {
return $this->pseudo;
}
public function setPseudo( string $pseudo ): self {
$this->pseudo = $pseudo;
return $this;
}
public function displayForAdmin() {
return [
'pseudo' => $this->getPseudo(),
'modifier_token' => $this->getModifierToken(),
'created_at' => $this->getCreatedAtAsString(),
];
}
public function getModifierToken(): ?string {
return $this->modifierToken;
}
public function setModifierToken( string $modifierToken ): self {
$this->modifierToken = $modifierToken;
return $this;
}
public function getId(): ?int { public function getId(): ?int {
return $this->id; return $this->id;
@ -127,6 +81,16 @@ class Owner {
return $this; return $this;
} }
public function getPseudo(): ?string {
return $this->pseudo;
}
public function setPseudo( string $pseudo ): self {
$this->pseudo = $pseudo;
return $this;
}
/** /**
* @return Collection|Poll[] * @return Collection|Poll[]
*/ */
@ -211,6 +175,16 @@ class Owner {
return $this; return $this;
} }
public function getModifierToken(): ?string {
return $this->modifierToken;
}
public function setModifierToken( string $modifierToken ): self {
$this->modifierToken = $modifierToken;
return $this;
}
public function addComment( Comment $comment ): self { public function addComment( Comment $comment ): self {
if ( ! $this->comments->contains( $comment ) ) { if ( ! $this->comments->contains( $comment ) ) {
$this->comments[] = $comment; $this->comments[] = $comment;
@ -232,6 +206,16 @@ class Owner {
return $this; return $this;
} }
public function getCreatedAt(): ?\DateTimeInterface {
return $this->createdAt;
}
public function setCreatedAt( \DateTimeInterface $createdAt ): self {
$this->createdAt = $createdAt;
return $this;
}
public function getRequestedPollsDate() { public function getRequestedPollsDate() {
return $this->requestedPollsDate; return $this->requestedPollsDate;
} }

View File

@ -2,26 +2,17 @@
namespace App\Entity; namespace App\Entity;
use App\Traits\RandomTrait; use DateTimeInterface;
use App\Traits\TimeStampableTrait; use Doctrine\Common\Collections\ArrayCollection;
use DateTime; use Doctrine\Common\Collections\Collection;
use DateTimeInterface; use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection; use JMS\Serializer\Annotation as Serializer;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use ErrorException;
use JMS\Serializer\Annotation as Serializer;
/** /**
* @ORM\Entity(repositoryClass="App\Repository\PollRepository") * @ORM\Entity(repositoryClass="App\Repository\PollRepository")
* @Serializer\ExclusionPolicy("all") * @Serializer\ExclusionPolicy("all")
*/ */
class Poll { class Poll {
use RandomTrait;
use TimeStampableTrait;
/** /**
* @ORM\Id() * @ORM\Id()
* @ORM\GeneratedValue() * @ORM\GeneratedValue()
@ -49,7 +40,11 @@ class Poll {
* @Serializer\Type("string") * @Serializer\Type("string")
*/ */
public $description; public $description;
/**
* @ORM\Column(type="datetime" , options={"default"="CURRENT_TIMESTAMP"})
* @Serializer\Expose()
*/
public $creationDate;
/** /**
* @ORM\Column(type="datetime") * @ORM\Column(type="datetime")
* @Serializer\Expose() * @Serializer\Expose()
@ -102,7 +97,7 @@ class Poll {
* @Serializer\Type("smallint") * @Serializer\Type("smallint")
* @Serializer\Expose() * @Serializer\Expose()
*/ */
public $choicesMax = - 1; public $choicesMax = -1;
/** /**
* people can add comments * people can add comments
@ -173,12 +168,6 @@ class Poll {
* @Serializer\Type("ArrayCollection<App\Entity\Comment>") * @Serializer\Type("ArrayCollection<App\Entity\Comment>")
*/ */
public $comments; public $comments;
/**
* number of days from now for default expiracy date
* @var int
* @Serializer\Expose()
*/
public $defaultExpiracyDaysFromNow = 60;
/** /**
* vote restricted by a password in md5 format * vote restricted by a password in md5 format
* @ORM\Column(type="string", length=255, nullable=true) * @ORM\Column(type="string", length=255, nullable=true)
@ -190,129 +179,43 @@ class Poll {
* @Serializer\Type("string") * @Serializer\Type("string")
*/ */
private $adminKey; private $adminKey;
/**
* number of days from now for default expiracy date
* @var int
* @Serializer\Expose()
*/
public $defaultExpiracyDaysFromNow = 60;
private $maxChoicesLimit = 25; private $maxChoicesLimit = 25;
public function __construct() {
$this->initiate();
$this->setCreatedAt( new DateTime() );
$this->votes = new ArrayCollection();
$this->stacksOfVotes = new ArrayCollection();
$this->choices = new ArrayCollection();
$this->comments = new ArrayCollection();
}
private function initiate() {
$this->votes = new ArrayCollection();
$this->stacksOfVotes = new ArrayCollection();
$this->choices = new ArrayCollection();
$this->comments = new ArrayCollection();
$this->setAdminKey( $this->generateRandomKey() );
$this->setCreatedAt( new DateTime() );
$this->setExpiracyDate( $this->addDaysToDate(
new DateTime(),
$this->defaultExpiracyDaysFromNow
) );
$this->setAllowedAnswers( [ 'yes', 'maybe', 'no' ] );
}
public function setCreatedAt( DateTimeInterface $createdAt ): self {
$this->createdAt = $createdAt;
return $this;
}
public function displayForAdmin() {
$content = $this->display();
$content[ 'owner' ] = $this->getOwner()->displayForAdmin();
$content[ 'admin_key' ] = $this->getAdminKey();
$content[ 'password_hash' ] = $this->getPassword();
$content[ 'id' ] = $this->getId();
return $content;
}
// counts each number of answer for this choice
public function display() {
$computedAnswers = $this->computeAnswers();
$displayedStackOfVotes = [];
foreach ( $this->getStacksOfVotes() as $stack ) {
$displayedStackOfVotes[] = $stack->display();
}
$displayedChoices = [];
foreach ( $this->getChoices() as $choice ) {
$displayedChoices[] = $choice->display();
}
$displayedComments = [];
foreach ( $this->getComments() as $comment ) {
$displayedComments[] = $comment->display();
}
return [
'title' => $this->getTitle(),
'description' => $this->getDescription(),
'created_at' => $this->getCreatedAt()->format( 'c' ),
'expiracy_date' => $this->getExpiracyDate()->format( 'c' ),
'votes_max' => $this->getVotesMax(),
'choices_max' => $this->getChoicesMax(),
'kind' => $this->getKind(),
'allowed_answers' => $this->getAllowedAnswers(),
'votes_allowed' => $this->getVotesAllowed(),
'modification_policy' => $this->getModificationPolicy(),
'hide_results' => $this->getHideResults(),
'show_results_even_if_password' => $this->getShowResultEvenIfPasswords(),
'owner' => [
'pseudo' => $this->getOwner()->getPseudo(),
]
,
'password_protected' => $this->getPassword() ? 'yes' : 'no',
'max_score' => $computedAnswers[ 'max_score' ],
'choices' => $computedAnswers[ 'answers' ],
'stacks' => $displayedStackOfVotes,
'comments' => $displayedComments,
];
}
public function computeAnswers() { public function computeAnswers() {
// counts each number of answer for this choice
$computedArray = []; $computedArray = [];
$maxScore = 0; $maxScore = 0;
$scoreInfos = [
'score' => 0,
'yes' => [
'count' => 0,
'people' => [],
],
'maybe' => [
'count' => 0,
'people' => [],
],
'no' => [
'count' => 0,
'people' => [],
],
];
// first, prefill all choices
foreach ( $this->getChoices() as $choice ) {
$computedArray[ $choice->getId() ] = array_merge( $scoreInfos, $choice->display( $this->getKind() ) );
}
// then, compute stack of votes scores on each choice
foreach ( $this->getStacksOfVotes() as $stack_of_vote ) { foreach ( $this->getStacksOfVotes() as $stack_of_vote ) {
foreach ( $stack_of_vote->getVotes() as $vote ) { foreach ( $stack_of_vote->getVotes() as $vote ) {
$answer = $vote->getValue(); $answer = $vote->getValue();
$choice_id = $vote->getChoice()->getId(); $choice_id = $vote->getChoice()->getId();
$choice_url = $vote->getChoice()->getUrl();
if ( ! isset( $computedArray[ $choice_id ] ) ) { if ( ! isset( $computedArray[ $choice_id ] ) ) {
$computedArray[ $choice_id ] = [ $computedArray[ $choice_id ] = [
'id' => $choice_id, 'choice_id' => $choice_id,
'url' => $choice_url, 'choice_text' => $vote->getChoice()->getName(),
'name' => $vote->getChoice()->getName(), 'id' => $vote->getId(),
'score' => 0,
'yes' => [
'count' => 0,
'people' => [],
],
'maybe' => [
'count' => 0,
'people' => [],
],
'no' => [
'count' => 0,
'people' => [],
],
]; ];
} }
$computedArray[ $choice_id ][ $answer ][ 'count' ] ++; $computedArray[ $choice_id ][ $answer ][ 'count' ] ++;
@ -329,49 +232,106 @@ class Poll {
} }
} }
} }
$answersWithStats = [];
foreach ( $computedArray as $choice_stat ) {
$answersWithStats[] = $choice_stat;
}
return [ return [
'answers' => $answersWithStats, 'counts' => $computedArray,
'max_score' => $maxScore, 'maxScore' => $maxScore,
]; ];
} }
/** public function display() {
* @return Collection|Choice[] return [
*/ 'config' => $this,
public function getChoices(): Collection { 'password_protected' => $this->getPassword() ? 'yes' : 'no',
return $this->choices; 'answers' => $this->computeAnswers(),
];
} }
public function getKind(): ?string { public function __construct() {
return $this->kind;
$this->initiate();
} }
public function setKind( string $kind ): self {
$this->kind = $kind;
return $this; private function initiate() {
$this->votes = new ArrayCollection();
$this->stacksOfVotes = new ArrayCollection();
$this->choices = new ArrayCollection();
$this->comments = new ArrayCollection();
$this->setAdminKey( $this->generateAdminKey() );
$this->setCreationDate( new \DateTime() );
$this->setExpiracyDate( $this->addDaysToDate(
new \DateTime(),
$this->defaultExpiracyDaysFromNow
) );
$this->setAllowedAnswers( [ 'yes', 'maybe', 'no' ] );
} }
public function getStacksOfVotes() {
return $this->stacksOfVotes;
}
public function setStacksOfVotes( ?StackOfVotes $stacksOfVotes ): self { public function generateAdminKey() {
$this->stacksOfVotes = $stacksOfVotes; $rand = random_int( PHP_INT_MIN, PHP_INT_MAX );
return $this; return str_shuffle( md5( $rand ) . $rand . $this->random_str() );
} }
/** /**
* @return Collection|Comment[] * Generate a random string, using a cryptographically secure
* pseudorandom number generator (random_int)
*
* This function uses type hints now (PHP 7+ only), but it was originally
* written for PHP 5 as well.
*
* For PHP 7, random_int is a PHP core function
* For PHP 5.x, depends on https://github.com/paragonie/random_compat
*
* @param int $length How many characters do we want?
* @param string $keyspace A string of all possible characters
* to select from
*
* @return string
*/ */
public function getComments(): Collection { public function random_str(
return $this->comments; int $length = 64,
string $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
): string {
if ( $length < 1 ) {
throw new \RangeException( "Length must be a positive integer" );
}
$pieces = [];
$max = mb_strlen( $keyspace, '8bit' ) - 1;
for ( $i = 0 ; $i < $length ; ++ $i ) {
$pieces [] = $keyspace[ random_int( 0, $max ) ];
}
return implode( '', $pieces );
}
public function findChoiceById( int $id ) {
$choices = $this->getChoices();
$counter = 0;
// there must be something cleaner than this in Doctrine ArrayCollection
foreach ( $choices as $choice ) {
$counter ++;
if ( $counter > $this->maxChoicesLimit ) {
throw new \ErrorException( "max number of choices reached for this poll" );
}
if ( $choice && $choice->getId() == $id ) {
return $choice;
}
}
return null;
}
public function addDaysToDate( \DateTime $date, int $days ) {
$st = strtotime( $date->getTimestamp() );
return new \DateTime( $st );
}
public function getId(): ?int {
return $this->id;
} }
public function getTitle(): ?string { public function getTitle(): ?string {
@ -384,100 +344,22 @@ class Poll {
return $this; return $this;
} }
public function getDescription(): ?string { public function getCreationDate(): ?DateTimeInterface {
return $this->description; return $this->creationDate;
} }
public function setDescription( string $description ): self { public function setCreationDate( DateTimeInterface $creationDate ): self {
$this->description = $description; $this->creationDate = $creationDate;
return $this; return $this;
} }
public function getCreatedAt(): ?DateTimeInterface {
return $this->createdAt;
}
public function getExpiracyDate(): ?DateTimeInterface {
return $this->expiracyDate;
}
public function setExpiracyDate( DateTimeInterface $expiracyDate ): self { public function setExpiracyDate( DateTimeInterface $expiracyDate ): self {
$this->expiracyDate = $expiracyDate; $this->expiracyDate = $expiracyDate;
return $this; return $this;
} }
public function getVotesMax() {
return $this->votesMax;
}
public function setVotesMax( $votesMax ): self {
$this->votesMax = $votesMax;
return $this;
}
public function getChoicesMax() {
return $this->choicesMax;
}
public function setChoicesMax( $choicesMax ): self {
$this->choicesMax = $choicesMax;
return $this;
}
public function getAllowedAnswers(): ?array {
return $this->allowedAnswers;
}
public function setAllowedAnswers( array $allowedAnswers ): self {
$this->allowedAnswers = $allowedAnswers;
return $this;
}
public function getVotesAllowed(): ?bool {
return $this->votesAllowed;
}
public function setVotesAllowed( ?bool $votesAllowed ): self {
$this->votesAllowed = $votesAllowed;
return $this;
}
public function getModificationPolicy(): ?string {
return $this->modificationPolicy;
}
public function setModificationPolicy( string $modificationPolicy ): self {
$this->modificationPolicy = $modificationPolicy;
return $this;
}
public function getHideResults(): ?bool {
return $this->hideResults;
}
public function setHideResults( bool $hideResults ): self {
$this->hideResults = $hideResults;
return $this;
}
public function getShowResultEvenIfPasswords(): ?bool {
return $this->showResultEvenIfPasswords;
}
public function setShowResultEvenIfPasswords( bool $showResultEvenIfPasswords ): self {
$this->showResultEvenIfPasswords = $showResultEvenIfPasswords;
return $this;
}
public function getOwner(): ?Owner { public function getOwner(): ?Owner {
return $this->owner; return $this->owner;
} }
@ -488,15 +370,13 @@ class Poll {
return $this; return $this;
} }
public function getPassword(): ?string { /**
return $this->password; * @return Collection|Vote[]
*/
public function getVotes(): Collection {
return $this->votes;
} }
public function setPassword( string $password ): self {
$this->password = md5( $password );
return $this;
}
public function getAdminKey(): ?string { public function getAdminKey(): ?string {
return $this->adminKey; return $this->adminKey;
@ -508,34 +388,24 @@ class Poll {
return $this; return $this;
} }
public function getId(): ?int { public function getDescription(): ?string {
return $this->id; return $this->description;
} }
public function findChoiceById( int $id ) { public function setDescription( string $description ): self {
$this->description = $description;
$choices = $this->getChoices(); return $this;
$counter = 0;
// there must be something cleaner than this in Doctrine ArrayCollection
foreach ( $choices as $choice ) {
$counter ++;
if ( $counter > $this->maxChoicesLimit ) {
throw new ErrorException( "max number of choices reached for this poll" );
}
if ( $choice && $choice->getId() == $id ) {
return $choice;
}
}
return null;
} }
/** public function getKind(): ?string {
* @return Collection|Vote[] return $this->kind;
*/ }
public function getVotes(): Collection {
return $this->votes; public function setKind( string $kind ): self {
$this->kind = $kind;
return $this;
} }
public function getCustomUrl(): ?string { public function getCustomUrl(): ?string {
@ -548,6 +418,26 @@ class Poll {
return $this; return $this;
} }
public function getPassword(): ?string {
return $this->password;
}
public function setPassword( string $password ): self {
$this->password = md5( $password );
return $this;
}
public function getModificationPolicy(): ?string {
return $this->modificationPolicy;
}
public function setModificationPolicy( string $modificationPolicy ): self {
$this->modificationPolicy = $modificationPolicy;
return $this;
}
public function getMailOnComment(): ?bool { public function getMailOnComment(): ?bool {
return $this->mailOnComment; return $this->mailOnComment;
} }
@ -568,6 +458,34 @@ class Poll {
return $this; return $this;
} }
public function getHideResults(): ?bool {
return $this->hideResults;
}
public function setHideResults( bool $hideResults ): self {
$this->hideResults = $hideResults;
return $this;
}
public function getShowResultEvenIfPasswords(): ?bool {
return $this->showResultEvenIfPasswords;
}
public function setShowResultEvenIfPasswords( bool $showResultEvenIfPasswords ): self {
$this->showResultEvenIfPasswords = $showResultEvenIfPasswords;
return $this;
}
/**
* @return Collection|Comment[]
*/
public function getComments(): Collection {
return $this->comments;
}
public function addComment( Comment $comment ): self { public function addComment( Comment $comment ): self {
if ( ! $this->comments->contains( $comment ) ) { if ( ! $this->comments->contains( $comment ) ) {
$this->comments[] = $comment; $this->comments[] = $comment;
@ -589,6 +507,17 @@ class Poll {
return $this; return $this;
} }
public function getStacksOfVotes() {
return $this->stacksOfVotes;
}
public function setStacksOfVotes( ?StackOfVotes $stacksOfVotes ): self {
$this->stacksOfVotes = $stacksOfVotes;
return $this;
}
public function addStackOfVote( StackOfVotes $stackOfVote ): self { public function addStackOfVote( StackOfVotes $stackOfVote ): self {
if ( ! $this->stacksOfVotes->contains( $stackOfVote ) ) { if ( ! $this->stacksOfVotes->contains( $stackOfVote ) ) {
$this->stacksOfVotes[] = $stackOfVote; $this->stacksOfVotes[] = $stackOfVote;
@ -610,6 +539,10 @@ class Poll {
return $this; return $this;
} }
public function getExpiracyDate(): ?\DateTimeInterface {
return $this->expiracyDate;
}
public function addVote( Vote $vote ): self { public function addVote( Vote $vote ): self {
if ( ! $this->votes->contains( $vote ) ) { if ( ! $this->votes->contains( $vote ) ) {
$this->votes[] = $vote; $this->votes[] = $vote;
@ -631,6 +564,13 @@ class Poll {
return $this; return $this;
} }
/**
* @return Collection|Choice[]
*/
public function getChoices(): Collection {
return $this->choices;
}
public function addTextChoiceArray( array $choiceTextArray ): self { public function addTextChoiceArray( array $choiceTextArray ): self {
foreach ( $choiceTextArray as $text ) { foreach ( $choiceTextArray as $text ) {
$newChoice = new Choice(); $newChoice = new Choice();
@ -641,17 +581,13 @@ class Poll {
return $this; return $this;
} }
public function addChoice( Choice $choice ): self {
if ( ! is_null( $this->choices ) ) {
if ( ! $this->choices->contains( $choice ) ) {
$this->choices[] = $choice;
$choice->setPoll( $this );
}
} else {
$this->choices[] = $choice;
$choice->setPoll( $this );
}
public function getAllowedAnswers(): ?array {
return $this->allowedAnswers;
}
public function setAllowedAnswers( array $allowedAnswers ): self {
$this->allowedAnswers = $allowedAnswers;
return $this; return $this;
} }
@ -677,6 +613,21 @@ class Poll {
return $this; return $this;
} }
public function addChoice( Choice $choice ): self {
if ( ! is_null( $this->choices ) ) {
if ( ! $this->choices->contains( $choice ) ) {
$this->choices[] = $choice;
$choice->setPoll( $this );
}
} else {
$this->choices[] = $choice;
$choice->setPoll( $this );
}
return $this;
}
public function removeChoice( Choice $choice ): self { public function removeChoice( Choice $choice ): self {
if ( $this->choices->contains( $choice ) ) { if ( $this->choices->contains( $choice ) ) {
$this->choices->removeElement( $choice ); $this->choices->removeElement( $choice );
@ -689,6 +640,36 @@ class Poll {
return $this; return $this;
} }
public function getVotesAllowed(): ?bool {
return $this->votesAllowed;
}
public function setVotesAllowed( ?bool $votesAllowed ): self {
$this->votesAllowed = $votesAllowed;
return $this;
}
public function getVotesMax() {
return $this->votesMax;
}
public function setVotesMax( $votesMax ): self {
$this->votesMax = $votesMax;
return $this;
}
public function getChoicesMax() {
return $this->choicesMax;
}
public function setChoicesMax( $choicesMax ): self {
$this->choicesMax = $choicesMax;
return $this;
}
public function getCommentsAllowed(): ?bool { public function getCommentsAllowed(): ?bool {
return $this->commentsAllowed; return $this->commentsAllowed;
} }

View File

@ -2,8 +2,6 @@
namespace App\Entity; namespace App\Entity;
use App\Traits\TimeStampableTrait;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
@ -16,9 +14,12 @@ use JMS\Serializer\Annotation as Serializer;
* @Serializer\ExclusionPolicy("all") * @Serializer\ExclusionPolicy("all")
*/ */
class StackOfVotes { class StackOfVotes {
/**
use TimeStampableTrait; * @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/** /**
* @ORM\Column(type="string", length=255) * @ORM\Column(type="string", length=255)
* @Serializer\Type("string") * @Serializer\Type("string")
@ -30,12 +31,6 @@ class StackOfVotes {
* @Serializer\Expose() * @Serializer\Expose()
*/ */
public $votes; public $votes;
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/** /**
* @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="stacksOfVotes", cascade={"persist"}) * @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="stacksOfVotes", cascade={"persist"})
*/ */
@ -47,58 +42,33 @@ class StackOfVotes {
*/ */
private $owner; private $owner;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $ip;
public function __construct() {
$this->setCreatedAt( new DateTime() );
$this->votes = new ArrayCollection();
}
public function display() { public function display() {
$votes = $this->getVotes();
$tab = [ $tab = [
// 'id' => $this->getId(), 'id' => $this->getId(),
// 'modifier_token' => $this->getOwner()->getModifierToken(), // 'modifier_token' => $this->getOwner()->getModifierToken(),
'pseudo' => $this->getPseudo(), 'pseudo' => '',
'created_at' => $this->getCreatedAtAsString(), 'creation_date' => '',
'votes' => [], 'votes' => [],
]; ];
// prefill votes with all choices ids // prefill votes with all choices ids
// foreach ( $this->getPoll()->getChoices() as $choice ) { foreach ( $this->getPoll()->getChoices() as $choice ) {
// $tab[ 'votes' ][ $choice->getId() ] = [ $tab[ 'votes' ][ $choice->getId() ] = [
// 'choice_id' => $choice->getId(), 'choice_id' => $choice->getId(),
// 'value' => null, 'name' => $choice->getName(),
// ]; ];
// } }
foreach ( $votes as $vote ) { foreach ( $this->getVotes() as $vote ) {
$tab[ 'votes' ][ $vote->getChoice()->getId() ] = $vote->display(); // $tab[ 'votes' ][ $vote->getChoice()->getId() ] = $vote->display();
$tab[ 'votes' ][ $vote->getChoice()->getId() ][ 'stack_id' ] = $this->getId();
$tab[ 'pseudo' ] = $this->getPseudo();
$tab[ 'creation_date' ] = $vote->getCreationDate();
} }
return $tab; return $tab;
} }
/**
* @return Collection|poll[]
*/
public function getVotes(): Collection {
return $this->votes;
}
public function getPseudo(): ?string {
return $this->pseudo;
}
public function setPseudo( ?string $pseudo ): self {
$this->pseudo = $pseudo;
return $this;
}
/** /**
* @ORM\PrePersist * @ORM\PrePersist
*/ */
@ -106,20 +76,21 @@ class StackOfVotes {
$this->setPseudo( $this->getOwner()->getPseudo() ); $this->setPseudo( $this->getOwner()->getPseudo() );
} }
public function getOwner(): ?Owner { public function __construct() {
return $this->owner; $this->votes = new ArrayCollection();
}
public function setOwner( ?Owner $owner ): self {
$this->owner = $owner;
return $this;
} }
public function getId(): ?int { public function getId(): ?int {
return $this->id; return $this->id;
} }
/**
* @return Collection|poll[]
*/
public function getVotes(): Collection {
return $this->votes;
}
public function addVote( Vote $vote ): self { public function addVote( Vote $vote ): self {
if ( ! $this->votes->contains( $vote ) ) { if ( ! $this->votes->contains( $vote ) ) {
$vote->setPoll( $this->getPoll() ); $vote->setPoll( $this->getPoll() );
@ -131,16 +102,6 @@ class StackOfVotes {
return $this; return $this;
} }
public function getPoll(): ?Poll {
return $this->poll;
}
public function setPoll( ?Poll $poll ): self {
$this->poll = $poll;
return $this;
}
public function removeVote( Vote $vote ): self { public function removeVote( Vote $vote ): self {
if ( $this->votes->contains( $vote ) ) { if ( $this->votes->contains( $vote ) ) {
$this->votes->removeElement( $vote ); $this->votes->removeElement( $vote );
@ -153,12 +114,32 @@ class StackOfVotes {
return $this; return $this;
} }
public function getIp(): ?string { public function getPseudo(): ?string {
return $this->ip; return $this->pseudo;
} }
public function setIp( string $ip ): self { public function setPseudo( ?string $pseudo ): self {
$this->ip = $ip; $this->pseudo = $pseudo;
return $this;
}
public function getOwner(): ?Owner {
return $this->owner;
}
public function setOwner( ?Owner $owner ): self {
$this->owner = $owner;
return $this;
}
public function getPoll(): ?Poll {
return $this->poll;
}
public function setPoll( ?Poll $poll ): self {
$this->poll = $poll;
return $this; return $this;
} }

View File

@ -1,130 +1,124 @@
<?php <?php
namespace App\Entity; namespace App\Entity;
use App\Traits\TimeStampableTrait; use DateTimeInterface;
use DateTime; use Doctrine\ORM\Mapping as ORM;
use DateTimeInterface; use JMS\Serializer\Annotation as Serializer;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
/**
* @ORM\Entity(repositoryClass="App\Repository\VoteRepository")
* @Serializer\ExclusionPolicy("all")
*/
class Vote {
use TimeStampableTrait;
/** /**
* for a text kind of choice: could be "yes" "no" "maybe" and empty. * @ORM\Entity(repositoryClass="App\Repository\VoteRepository")
* for a date kind, the choice linked is equivalent to the value selected * @Serializer\ExclusionPolicy("all")
* @ORM\Column(type="string", length=255, nullable=true)
* @Serializer\Type("string")
* @Serializer\Expose()
*/ */
public $value; class Vote {
/**
/** * for a text kind of choice: could be "yes" "no" "maybe" and empty.
* @ORM\ManyToOne(targetEntity="App\Entity\Choice", inversedBy="votes", cascade={"persist"}) * for a date kind, the choice linked is equivalent to the value selected
* @ORM\JoinColumn(nullable=false) * @ORM\Column(type="string", length=255, nullable=true)
* @Serializer\Type("App\Entity\choice") * @Serializer\Type("string")
* @Serializer\Expose() * @Serializer\Expose()
*/ */
public $choice; public $value;
/** /**
* @ORM\Id() * @ORM\Column(type="datetime" , options={"default"="CURRENT_TIMESTAMP"})
* @ORM\GeneratedValue() * @Serializer\Type("datetime")
* @ORM\Column(type="integer") * @Serializer\Expose()
* @Serializer\Type("integer") */
* @Serializer\Expose() public $creationDate;
*/ /**
private $id; * @ORM\ManyToOne(targetEntity="App\Entity\Choice", inversedBy="votes", cascade={"persist"})
/** * @ORM\JoinColumn(nullable=false)
* @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="votes", cascade={"persist"}) * @Serializer\Type("App\Entity\choice")
* @ORM\JoinColumn(nullable=false) * @Serializer\Expose()
*/ */
private $poll; public $choice;
/** /**
* @ORM\ManyToOne(targetEntity="App\Entity\StackOfVotes", inversedBy="votes", cascade={"persist"}) * @ORM\Id()
* @ORM\JoinColumn(nullable=false) * @ORM\GeneratedValue()
* @Serializer\Type("App\Entity\StackOfVotes") * @ORM\Column(type="integer")
*/ * @Serializer\Type("integer")
private $stacksOfVotes; * @Serializer\Expose()
*/
public function __construct() { private $id;
$this->setCreatedAt( new DateTime() ); /**
} * @ORM\ManyToOne(targetEntity="App\Entity\Poll", inversedBy="votes", cascade={"persist"})
* @ORM\JoinColumn(nullable=false)
public function display() { */
$value = $this->getValue(); private $poll;
if ( ! $value ) { /**
return null; * @ORM\ManyToOne(targetEntity="App\Entity\StackOfVotes", inversedBy="votes", cascade={"persist"})
} else { * @ORM\JoinColumn(nullable=false)
* @Serializer\Type("App\Entity\StackOfVotes")
*/
private $stacksOfVotes;
public function display() {
return [ return [
'id' => $this->getId(), 'id' => $this->getId(),
'value' => $this->getValue(), 'value' => $this->getValue(),
'choice_id' => $this->getChoice()->getId(), 'choice_id' => $this->getChoice()->getId(),
'text' => $this->getChoice()->getName(), 'text' => $this->getChoice()->getName(),
]; ];
} }
}
public function getValue(): ?string { public function __construct() {
return $this->value; $this->setCreationDate( new \DateTime() );
}
public function setValue( ?string $value ): self {
$this->value = $value;
return $this;
}
public function getId(): ?int {
return $this->id;
}
public function getChoice(): ?Choice {
return $this->choice;
}
public function setChoice( ?Choice $choice ): self {
$this->choice = $choice;
return $this;
}
public function getPoll(): ?Poll {
return $this->poll;
}
public function setPoll( ?Poll $poll ): self {
$this->poll = $poll;
if ( $poll ) {
$poll->addVote( $this );
} }
return $this; public function getId(): ?int {
return $this->id;
}
public function getPoll(): ?Poll {
return $this->poll;
}
public function setPoll( ?Poll $poll ): self {
$this->poll = $poll;
if ( $poll ) {
$poll->addVote( $this );
}
return $this;
}
public function getChoice(): ?Choice {
return $this->choice;
}
public function setChoice( ?Choice $choice ): self {
$this->choice = $choice;
return $this;
}
public function getValue(): ?string {
return $this->value;
}
public function setValue( ?string $value ): self {
$this->value = $value;
return $this;
}
public function getCreationDate(): ?DateTimeInterface {
return $this->creationDate;
}
public function setCreationDate( DateTimeInterface $creationDate ): self {
$this->creationDate = $creationDate;
return $this;
}
public function getStacksOfVotes(): ?StackOfVotes {
return $this->stacksOfVotes;
}
public function setStacksOfVotes( ?StackOfVotes $stacksOfVotes ): self {
$this->stacksOfVotes = $stacksOfVotes;
return $this;
}
} }
public function getCreationDate(): ?DateTimeInterface {
return $this->creationDate;
}
public function setCreationDate( DateTimeInterface $creationDate ): self {
$this->creationDate = $creationDate;
return $this;
}
public function getStacksOfVotes(): ?StackOfVotes {
return $this->stacksOfVotes;
}
public function setStacksOfVotes( ?StackOfVotes $stacksOfVotes ): self {
$this->stacksOfVotes = $stacksOfVotes;
return $this;
}
}

12
src/Entity/timedTrait.php Executable file
View File

@ -0,0 +1,12 @@
<?php
namespace App\Traits;
use Doctrine\ORM\Mapping as ORM;
trait Timed {
/**
* @ORM\Column(type="datetime" , options={"default"="CURRENT_TIMESTAMP"})
*/
private $createdAt;
}

View File

@ -7,29 +7,33 @@ use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
class PollType extends AbstractType { class PollType extends AbstractType
public function buildForm( FormBuilderInterface $builder, array $options ) { {
$builder public function buildForm(FormBuilderInterface $builder, array $options)
->add( 'title' ) {
->add( 'customUrl' ) $builder
->add( 'description' ) ->add('title')
->add( 'createdAt' ) ->add('customUrl')
->add( 'expiracyDate' ) ->add('description')
->add( 'kind' ) ->add('creationDate')
->add( 'allowedAnswers' ) ->add('expiracyDate')
->add( 'modificationPolicy' ) ->add('kind')
->add( 'mailOnComment' ) ->add('allowedAnswers')
->add( 'mailOnVote' ) ->add('modificationPolicy')
->add( 'hideResults' ) ->add('mailOnComment')
->add( 'showResultEvenIfPasswords' ) ->add('mailOnVote')
->add( 'password' ) ->add('hideResults')
->add( 'adminKey' ) ->add('showResultEvenIfPasswords')
->add( 'owner' ); ->add('password')
} ->add('adminKey')
->add('owner')
;
}
public function configureOptions( OptionsResolver $resolver ) { public function configureOptions(OptionsResolver $resolver)
$resolver->setDefaults( [ {
'data_class' => Poll::class, $resolver->setDefaults([
] ); 'data_class' => Poll::class,
} ]);
}
} }

View File

@ -6,31 +6,33 @@ use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\HttpKernel\Kernel as BaseKernel; use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
use function dirname;
class Kernel extends BaseKernel { class Kernel extends BaseKernel
use MicroKernelTrait; {
use MicroKernelTrait;
protected function configureContainer( ContainerConfigurator $container ): void { protected function configureContainer(ContainerConfigurator $container): void
$container->import( '../config/{packages}/*.yaml' ); {
$container->import( '../config/{packages}/' . $this->environment . '/*.yaml' ); $container->import('../config/{packages}/*.yaml');
$container->import('../config/{packages}/'.$this->environment.'/*.yaml');
if ( is_file( dirname( __DIR__ ) . '/config/services.yaml' ) ) { if (is_file(\dirname(__DIR__).'/config/services.yaml')) {
$container->import( '../config/services.yaml' ); $container->import('../config/services.yaml');
$container->import( '../config/{services}_' . $this->environment . '.yaml' ); $container->import('../config/{services}_'.$this->environment.'.yaml');
} elseif ( is_file( $path = dirname( __DIR__ ) . '/config/services.php' ) ) { } elseif (is_file($path = \dirname(__DIR__).'/config/services.php')) {
( require $path )( $container->withPath( $path ), $this ); (require $path)($container->withPath($path), $this);
} }
} }
protected function configureRoutes( RoutingConfigurator $routes ): void { protected function configureRoutes(RoutingConfigurator $routes): void
$routes->import( '../config/{routes}/' . $this->environment . '/*.yaml' ); {
$routes->import( '../config/{routes}/*.yaml' ); $routes->import('../config/{routes}/'.$this->environment.'/*.yaml');
$routes->import('../config/{routes}/*.yaml');
if ( is_file( dirname( __DIR__ ) . '/config/routes.yaml' ) ) { if (is_file(\dirname(__DIR__).'/config/routes.yaml')) {
$routes->import( '../config/routes.yaml' ); $routes->import('../config/routes.yaml');
} elseif ( is_file( $path = dirname( __DIR__ ) . '/config/routes.php' ) ) { } elseif (is_file($path = \dirname(__DIR__).'/config/routes.php')) {
( require $path )( $routes->withPath( $path ), $this ); (require $path)($routes->withPath($path), $this);
} }
} }
} }

View File

@ -7,42 +7,44 @@ use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\Common\Persistence\ManagerRegistry;
/** /**
* @method Choice|null find( $id, $lockMode = null, $lockVersion = null ) * @method Choice|null find($id, $lockMode = null, $lockVersion = null)
* @method Choice|null findOneBy( array $criteria, array $orderBy = null ) * @method Choice|null findOneBy(array $criteria, array $orderBy = null)
* @method Choice[] findAll() * @method Choice[] findAll()
* @method Choice[] findBy( array $criteria, array $orderBy = null, $limit = null, $offset = null ) * @method Choice[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/ */
class ChoiceRepository extends ServiceEntityRepository { class ChoiceRepository extends ServiceEntityRepository
public function __construct( ManagerRegistry $registry ) { {
parent::__construct( $registry, Choice::class ); public function __construct(ManagerRegistry $registry)
} {
parent::__construct($registry, Choice::class);
}
// /** // /**
// * @return Choice[] Returns an array of Choice objects // * @return Choice[] Returns an array of Choice objects
// */ // */
/* /*
public function findByExampleField($value) public function findByExampleField($value)
{ {
return $this->createQueryBuilder('c') return $this->createQueryBuilder('c')
->andWhere('c.exampleField = :val') ->andWhere('c.exampleField = :val')
->setParameter('val', $value) ->setParameter('val', $value)
->orderBy('c.id', 'ASC') ->orderBy('c.id', 'ASC')
->setMaxResults(10) ->setMaxResults(10)
->getQuery() ->getQuery()
->getResult() ->getResult()
; ;
} }
*/ */
/* /*
public function findOneBySomeField($value): ?Choice public function findOneBySomeField($value): ?Choice
{ {
return $this->createQueryBuilder('c') return $this->createQueryBuilder('c')
->andWhere('c.exampleField = :val') ->andWhere('c.exampleField = :val')
->setParameter('val', $value) ->setParameter('val', $value)
->getQuery() ->getQuery()
->getOneOrNullResult() ->getOneOrNullResult()
; ;
} }
*/ */
} }

View File

@ -7,42 +7,44 @@ use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\Common\Persistence\ManagerRegistry;
/** /**
* @method Comment|null find( $id, $lockMode = null, $lockVersion = null ) * @method Comment|null find($id, $lockMode = null, $lockVersion = null)
* @method Comment|null findOneBy( array $criteria, array $orderBy = null ) * @method Comment|null findOneBy(array $criteria, array $orderBy = null)
* @method Comment[] findAll() * @method Comment[] findAll()
* @method Comment[] findBy( array $criteria, array $orderBy = null, $limit = null, $offset = null ) * @method Comment[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/ */
class CommentRepository extends ServiceEntityRepository { class CommentRepository extends ServiceEntityRepository
public function __construct( ManagerRegistry $registry ) { {
parent::__construct( $registry, Comment::class ); public function __construct(ManagerRegistry $registry)
} {
parent::__construct($registry, Comment::class);
}
// /** // /**
// * @return Comment[] Returns an array of Comment objects // * @return Comment[] Returns an array of Comment objects
// */ // */
/* /*
public function findByExampleField($value) public function findByExampleField($value)
{ {
return $this->createQueryBuilder('c') return $this->createQueryBuilder('c')
->andWhere('c.exampleField = :val') ->andWhere('c.exampleField = :val')
->setParameter('val', $value) ->setParameter('val', $value)
->orderBy('c.id', 'ASC') ->orderBy('c.id', 'ASC')
->setMaxResults(10) ->setMaxResults(10)
->getQuery() ->getQuery()
->getResult() ->getResult()
; ;
} }
*/ */
/* /*
public function findOneBySomeField($value): ?Comment public function findOneBySomeField($value): ?Comment
{ {
return $this->createQueryBuilder('c') return $this->createQueryBuilder('c')
->andWhere('c.exampleField = :val') ->andWhere('c.exampleField = :val')
->setParameter('val', $value) ->setParameter('val', $value)
->getQuery() ->getQuery()
->getOneOrNullResult() ->getOneOrNullResult()
; ;
} }
*/ */
} }

View File

@ -7,42 +7,44 @@ use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\Common\Persistence\ManagerRegistry;
/** /**
* @method Owner|null find( $id, $lockMode = null, $lockVersion = null ) * @method Owner|null find($id, $lockMode = null, $lockVersion = null)
* @method Owner|null findOneBy( array $criteria, array $orderBy = null ) * @method Owner|null findOneBy(array $criteria, array $orderBy = null)
* @method Owner[] findAll() * @method Owner[] findAll()
* @method Owner[] findBy( array $criteria, array $orderBy = null, $limit = null, $offset = null ) * @method Owner[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/ */
class OwnerRepository extends ServiceEntityRepository { class OwnerRepository extends ServiceEntityRepository
public function __construct( ManagerRegistry $registry ) { {
parent::__construct( $registry, Owner::class ); public function __construct(ManagerRegistry $registry)
} {
parent::__construct($registry, Owner::class);
}
// /** // /**
// * @return Owner[] Returns an array of Owner objects // * @return Owner[] Returns an array of Owner objects
// */ // */
/* /*
public function findByExampleField($value) public function findByExampleField($value)
{ {
return $this->createQueryBuilder('o') return $this->createQueryBuilder('o')
->andWhere('o.exampleField = :val') ->andWhere('o.exampleField = :val')
->setParameter('val', $value) ->setParameter('val', $value)
->orderBy('o.id', 'ASC') ->orderBy('o.id', 'ASC')
->setMaxResults(10) ->setMaxResults(10)
->getQuery() ->getQuery()
->getResult() ->getResult()
; ;
} }
*/ */
/* /*
public function findOneBySomeField($value): ?Owner public function findOneBySomeField($value): ?Owner
{ {
return $this->createQueryBuilder('o') return $this->createQueryBuilder('o')
->andWhere('o.exampleField = :val') ->andWhere('o.exampleField = :val')
->setParameter('val', $value) ->setParameter('val', $value)
->getQuery() ->getQuery()
->getOneOrNullResult() ->getOneOrNullResult()
; ;
} }
*/ */
} }

View File

@ -5,46 +5,48 @@ namespace App\Repository;
use App\Entity\Poll; use App\Entity\Poll;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ManagerRegistry;
use MongoDB\Driver\Manager;
/** /**
* @method Poll|null find( $id, $lockMode = null, $lockVersion = null ) * @method Poll|null find($id, $lockMode = null, $lockVersion = null)
* @method Poll|null findOneBy( array $criteria, array $orderBy = null ) * @method Poll|null findOneBy(array $criteria, array $orderBy = null)
* @method Poll[] findAll() * @method Poll[] findAll()
* @method Poll[] findBy( array $criteria, array $orderBy = null, $limit = null, $offset = null ) * @method Poll[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/ */
class PollRepository extends ServiceEntityRepository { class PollRepository extends ServiceEntityRepository
public function __construct( {
ManagerRegistry $registry public function __construct(ManagerRegistry
) { $registry)
parent::__construct( $registry, Poll::class ); {
} parent::__construct($registry, Poll::class);
}
// /** // /**
// * @return Poll[] Returns an array of Poll objects // * @return Poll[] Returns an array of Poll objects
// */ // */
/* /*
public function findByExampleField($value) public function findByExampleField($value)
{ {
return $this->createQueryBuilder('p') return $this->createQueryBuilder('p')
->andWhere('p.exampleField = :val') ->andWhere('p.exampleField = :val')
->setParameter('val', $value) ->setParameter('val', $value)
->orderBy('p.id', 'ASC') ->orderBy('p.id', 'ASC')
->setMaxResults(10) ->setMaxResults(10)
->getQuery() ->getQuery()
->getResult() ->getResult()
; ;
} }
*/ */
/* /*
public function findOneBySomeField($value): ?Poll public function findOneBySomeField($value): ?Poll
{ {
return $this->createQueryBuilder('p') return $this->createQueryBuilder('p')
->andWhere('p.exampleField = :val') ->andWhere('p.exampleField = :val')
->setParameter('val', $value) ->setParameter('val', $value)
->getQuery() ->getQuery()
->getOneOrNullResult() ->getOneOrNullResult()
; ;
} }
*/ */
} }

View File

@ -7,42 +7,44 @@ use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\Common\Persistence\ManagerRegistry;
/** /**
* @method StackOfVotes|null find( $id, $lockMode = null, $lockVersion = null ) * @method StackOfVotes|null find($id, $lockMode = null, $lockVersion = null)
* @method StackOfVotes|null findOneBy( array $criteria, array $orderBy = null ) * @method StackOfVotes|null findOneBy(array $criteria, array $orderBy = null)
* @method StackOfVotes[] findAll() * @method StackOfVotes[] findAll()
* @method StackOfVotes[] findBy( array $criteria, array $orderBy = null, $limit = null, $offset = null ) * @method StackOfVotes[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/ */
class StackOfVotesRepository extends ServiceEntityRepository { class StackOfVotesRepository extends ServiceEntityRepository
public function __construct( ManagerRegistry $registry ) { {
parent::__construct( $registry, StackOfVotes::class ); public function __construct(ManagerRegistry $registry)
} {
parent::__construct($registry, StackOfVotes::class);
}
// /** // /**
// * @return StackOfVotes[] Returns an array of StackOfVotes objects // * @return StackOfVotes[] Returns an array of StackOfVotes objects
// */ // */
/* /*
public function findByExampleField($value) public function findByExampleField($value)
{ {
return $this->createQueryBuilder('s') return $this->createQueryBuilder('s')
->andWhere('s.exampleField = :val') ->andWhere('s.exampleField = :val')
->setParameter('val', $value) ->setParameter('val', $value)
->orderBy('s.id', 'ASC') ->orderBy('s.id', 'ASC')
->setMaxResults(10) ->setMaxResults(10)
->getQuery() ->getQuery()
->getResult() ->getResult()
; ;
} }
*/ */
/* /*
public function findOneBySomeField($value): ?StackOfVotes public function findOneBySomeField($value): ?StackOfVotes
{ {
return $this->createQueryBuilder('s') return $this->createQueryBuilder('s')
->andWhere('s.exampleField = :val') ->andWhere('s.exampleField = :val')
->setParameter('val', $value) ->setParameter('val', $value)
->getQuery() ->getQuery()
->getOneOrNullResult() ->getOneOrNullResult()
; ;
} }
*/ */
} }

View File

@ -7,42 +7,44 @@ use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\Common\Persistence\ManagerRegistry;
/** /**
* @method Vote|null find( $id, $lockMode = null, $lockVersion = null ) * @method Vote|null find($id, $lockMode = null, $lockVersion = null)
* @method Vote|null findOneBy( array $criteria, array $orderBy = null ) * @method Vote|null findOneBy(array $criteria, array $orderBy = null)
* @method Vote[] findAll() * @method Vote[] findAll()
* @method Vote[] findBy( array $criteria, array $orderBy = null, $limit = null, $offset = null ) * @method Vote[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/ */
class VoteRepository extends ServiceEntityRepository { class VoteRepository extends ServiceEntityRepository
public function __construct( ManagerRegistry $registry ) { {
parent::__construct( $registry, Vote::class ); public function __construct(ManagerRegistry $registry)
} {
parent::__construct($registry, Vote::class);
}
// /** // /**
// * @return Vote[] Returns an array of Vote objects // * @return Vote[] Returns an array of Vote objects
// */ // */
/* /*
public function findByExampleField($value) public function findByExampleField($value)
{ {
return $this->createQueryBuilder('v') return $this->createQueryBuilder('v')
->andWhere('v.exampleField = :val') ->andWhere('v.exampleField = :val')
->setParameter('val', $value) ->setParameter('val', $value)
->orderBy('v.id', 'ASC') ->orderBy('v.id', 'ASC')
->setMaxResults(10) ->setMaxResults(10)
->getQuery() ->getQuery()
->getResult() ->getResult()
; ;
} }
*/ */
/* /*
public function findOneBySomeField($value): ?Vote public function findOneBySomeField($value): ?Vote
{ {
return $this->createQueryBuilder('v') return $this->createQueryBuilder('v')
->andWhere('v.exampleField = :val') ->andWhere('v.exampleField = :val')
->setParameter('val', $value) ->setParameter('val', $value)
->getQuery() ->getQuery()
->getOneOrNullResult() ->getOneOrNullResult()
; ;
} }
*/ */
} }

View File

@ -12,7 +12,6 @@ use Exception;
use Swift_Mailer; use Swift_Mailer;
use Swift_Message; use Swift_Message;
use Swift_SmtpTransport; use Swift_SmtpTransport;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
class MailService { class MailService {
@ -50,7 +49,7 @@ class MailService {
* @param Owner $foundOwner * @param Owner $foundOwner
* @param Poll|null $poll * @param Poll|null $poll
* *
* @throws TransportExceptionInterface * @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
*/ */
public function sendCreationMailAction( Owner $foundOwner, Poll $poll = null ) { public function sendCreationMailAction( Owner $foundOwner, Poll $poll = null ) {
@ -67,12 +66,74 @@ class MailService {
return $this->sendMailWithVars( $config ); return $this->sendMailWithVars( $config );
} }
/**
* anti spam , limit to every minute TODO
*
* @param Owner $owner
*
* @return bool
*/
public function antispamCheck( Owner $owner ) {
// $lastSend = $admin_user->getRequestedPollsDate();
// $now = new \DateTime();
// if ( date_diff( $lastSend, $now ) < 60 ) {
// // too soon!
// die( 'too soon!' );
// }
// $admin_user->setRequestedPollsDate( $now );
// $em->persist( $admin_user );
// $em->flush();
return true;
}
/**
* send created polls to an owner
*
* @param Owner $owner
*
* @return int|void
* @throws Exception
* @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
*/
public function sendOwnerPollsAction( Owner $owner ) {
$config = [
'owner' => $owner,
'title' => 'Framadate | Mes sondages',
'email_template' => 'emails/owner-list.html.twig',
];
$this->sendMailWithVars( $config );
return 1;
}
/**
* @param Comment $comment
*
* @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
*/
public function sendCommentNotification( Comment $comment ) {
$config = [
'comment' => $comment,
'owner' => $comment->getOwner(),
'title' => 'Framadate | commentaire de ' . $comment->getOwner()->getPseudo() . ' _ sondage ' . $comment->getPoll()->getTitle(),
'email_template' => 'emails/comment-notification.html.twig',
];
$this->sendMailWithVars( $config );
}
/** /**
* generic way to send email with html template * generic way to send email with html template
* *
* @param $config * @param $config
* *
* @throws TransportExceptionInterface * @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
*/ */
public function sendMailWithVars( $config ) { public function sendMailWithVars( $config ) {
@ -148,64 +209,4 @@ class MailService {
} }
/**
* anti spam , limit to every minute TODO
*
* @param Owner $owner
*
* @return bool
*/
public function antispamCheck( Owner $owner ) {
// $lastSend = $admin_user->getRequestedPollsDate();
// $now = new \DateTime();
// if ( date_diff( $lastSend, $now ) < 60 ) {
// // too soon!
// die( 'too soon!' );
// }
// $admin_user->setRequestedPollsDate( $now );
// $em->persist( $admin_user );
// $em->flush();
return true;
}
/**
* send created polls to an owner
*
* @param Owner $owner
*
* @return int|void
* @throws Exception
* @throws TransportExceptionInterface
*/
public function sendOwnerPollsAction( Owner $owner ) {
$config = [
'owner' => $owner,
'title' => 'Framadate | Mes sondages',
'email_template' => 'emails/owner-list.html.twig',
];
$this->sendMailWithVars( $config );
return 1;
}
/**
* @param Comment $comment
*
* @throws TransportExceptionInterface
*/
public function sendCommentNotification( Comment $comment ) {
$config = [
'comment' => $comment,
'owner' => $comment->getOwner(),
'title' => 'Framadate | commentaire de ' . $comment->getOwner()->getPseudo() . ' _ sondage ' . $comment->getPoll()->getTitle(),
'email_template' => 'emails/comment-notification.html.twig',
];
$this->sendMailWithVars( $config );
}
} }

View File

@ -1,45 +0,0 @@
<?php
namespace App\Traits;
trait RandomTrait {
public function generateRandomKey() {
$rand = random_int( PHP_INT_MIN, PHP_INT_MAX );
return str_shuffle( md5( $rand ) . $rand . $this->random_str() );
}
/**
* Generate a random string, using a cryptographically secure
* pseudorandom number generator (random_int)
*
* This function uses type hints now (PHP 7+ only), but it was originally
* written for PHP 5 as well.
*
* For PHP 7, random_int is a PHP core function
* For PHP 5.x, depends on https://github.com/paragonie/random_compat
*
* @param int $length How many characters do we want?
* @param string $keyspace A string of all possible characters
* to select from
*
* @return string
*/
public function random_str(
int $length = 64,
string $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
): string {
if ( $length < 1 ) {
throw new RangeException( "Length must be a positive integer" );
}
$pieces = [];
$max = mb_strlen( $keyspace, '8bit' ) - 1;
for ( $i = 0 ; $i < $length ; ++ $i ) {
$pieces [] = $keyspace[ random_int( 0, $max ) ];
}
return implode( '', $pieces );
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace App\Traits;
use DateInterval;
use DateTime;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
trait TimeStampableTrait {
/**
* @ORM\Column(type="datetime" , options={"default"="CURRENT_TIMESTAMP"})
*/
private $createdAt;
public function getCreatedAt(): ?DateTimeInterface {
return $this->createdAt;
}
public function setCreatedAt( DateTimeInterface $createdAt ): self {
$this->createdAt = $createdAt;
return $this;
}
public function getCreatedAtAsString(): string {
return $this->createdAt->format( 'c' );
}
public function addDaysToDate( DateTime $date, int $days ) {
return $date->add( new DateInterval( 'P' . $days . 'D' ) );
}
}

View File

@ -85,8 +85,6 @@ fi
git config --global diff.submodule log git config --global diff.submodule log
git submodule update git submodule update
git submodule foreach git reset --hard && git checkout master && git pull
cecho g "######################" cecho g "######################"
cecho g " check dependencies of the frontend with yarn " cecho g " check dependencies of the frontend with yarn "
cecho g "######################" cecho g "######################"
@ -139,9 +137,6 @@ mv polyfills-es5* es5-polyfills.js
mv polyfills* other-polyfills.js mv polyfills* other-polyfills.js
mv scripts* scripts.js mv scripts* scripts.js
mv styles* styles.css mv styles* styles.css
chown www-data:www-data . -R
cecho b " finished at ------- $(date) ------- " cecho b " finished at ------- $(date) ------- "
cecho g "##################################################################" cecho g "##################################################################"
cecho g " " cecho g " "