add comment anonymous, move route params to custom_url instead of id

This commit is contained in:
Tykayn 2022-02-14 13:52:51 +01:00 committed by tykayn
parent a005aa0f97
commit 5a463695c3
4 changed files with 208 additions and 145 deletions

View File

@ -174,14 +174,22 @@ DATABASE_URL=mysql://database_user:db_user_password@127.0.0.1:3306/database_name
this file is not versionned and should stay like this. this file is not versionned and should stay like this.
## cronjob to delete expired polls ## cronjob to delete expired polls
add this line in your crontab to run the clearance of expired polls everyday at 0h00.
```
0 0 * * * wget http://MYWEBSITE/api/v1/poll/clean-polls
```
you can open your crontabl in command line with : you can open your crontabl in command line with :
``` ```
crontab -e crontab -e
``` ```
add this line in your crontab to run the clearance of expired polls everyday at 0h00.
```
0 0 * * * wget http://MYWEBSITE/api/v1/poll/clean-polls
```
Cronjob to send mails from the swiftmailer spool.
```
* * * * * php /var/www/html/date-poll-api/bin/console swiftmailer:spool:send
```
you can disable the spooling, check the docs.
# About # About
made by B. Lemoine, aka Tykayn, for the framadate funky front end project, a polling libre software. made by B. Lemoine, aka Tykayn, for the framadate funky front end project, a polling libre software.

View File

@ -35,7 +35,7 @@ class PollController extends AbstractController {
} }
/** /**
* @Route("/new", name="poll_new", methods={"POST"}) * @Route("/new", name="poll_new_old", methods={"POST"})
*/ */
public function new( Request $request ): Response { public function new( Request $request ): Response {
$poll = new Poll(); $poll = new Poll();

View File

@ -9,7 +9,6 @@ use App\Entity\Poll;
use DateTime; use DateTime;
use FOS\RestBundle\Controller\Annotations\Delete; use FOS\RestBundle\Controller\Annotations\Delete;
use FOS\RestBundle\Controller\Annotations\Get; use FOS\RestBundle\Controller\Annotations\Get;
use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\Route; use FOS\RestBundle\Controller\Annotations\Route;
use JMS\Serializer\SerializerBuilder; use JMS\Serializer\SerializerBuilder;
use JMS\Serializer\SerializerInterface; use JMS\Serializer\SerializerInterface;
@ -20,161 +19,217 @@ use Symfony\Component\HttpFoundation\Response;
/** /**
* Class DefaultController * Class DefaultController
* @package App\Controller * @package App\Controller
* @Route("/api/v1/comment",name="api_") * @Route("/api/v1/comment",
* name="api_comment_")
*/ */
class CommentController extends EmailsController { class CommentController extends EmailsController
{
/** /**
* @Get( * @Get(
* path = "/poll/{id}", * path = "/poll/{customUrl}",
* name = "get_poll_comment", * name = "get_poll_comment"
* requirements = {"id"="\d+"} * )
* ) */
*/ public
public function getPollCommentsAction(
function getPollCommentsAction( 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;
} }
/** /**
* add a comment on a poll * add a comment on a poll
* @Post( * @Route(
* path = "/poll/{id}", * "/poll/{customUrl}",
* name = "new_comment", * "_new_comment",
* requirements = {"content"="\w+", "id"="\d+"} * methods={"POST"}
* ) * )
*/ */
public public
function newCommentAction( function newCommentAction(
Poll $poll, Poll $poll,
Request $request Request $request
) { )
if ( ! $poll ) { {
return $this->json( [ 'message' => 'poll not found' ], 404 );
}
$data = $request->getContent();
$serializer = SerializerBuilder::create()->build(); $data = json_decode($request->getContent(), true);
$comment = $serializer->deserialize( $data, 'App\Entity\Comment', 'json' ); // return $this->json(['pseudo' => $data["pseudo"]], 404);
$em = $this->getDoctrine()->getRepository( Owner::class ); if (!$poll) {
return $this->json(['message' => 'poll not found'], 404);
}
$data = json_decode( $data, true ); $comment = new Comment();
if ( ! isset( $data[ 'email' ] ) ) { $owner = new Owner();
return $this->json( [ "message" => "Incorrect JSON in request" ], 400 ); $owner
} ->setPseudo($data["pseudo"])
->setEmail('anonymous@example.com');
$foundOwner = $em->findOneByEmail( $data[ 'email' ] ); $comment->setOwner($owner)
// manage existing or new Owner ->setPseudo($data["pseudo"])
if ( ! $foundOwner ) { ->setText($data["text"])
$foundOwner = new Owner(); ->setCreatedAt(new DateTime())
$foundOwner->setPseudo( $data[ 'email' ] ) ->setPoll($poll);
->setEmail( $data[ 'email' ] ) $owner
->setModifierToken( uniqid( '', true ) ); ->addComment($comment);
}
// anti flood
$seconds_limit_lastpost = 5;
$emComment = $this->getDoctrine()->getRepository( Comment::class );
$lastCommentOfOwner = $emComment->findBy( [ 'owner' => $foundOwner ], [ 'id' => 'desc' ] );
// TODO anti flood by session / IP $em = $this->getDoctrine()->getManager();
$em->persist($owner);
$em->persist($comment);
$em->flush();
if ( $lastCommentOfOwner ) { if ($poll->getMailOnComment()) {
$this->sendCommentNotificationAction($owner, $comment);
}
// check time of last comment return $this->json( $comment->display(),
$now = new DateTime();
$now = $now->format( 'Y-m-d H:i:s' );
$date_first = strtotime( $lastCommentOfOwner[ 0 ]->getCreatedAt()->format( 'Y-m-d H:i:s' ) );
$date_second = strtotime( $now );
if ( ( $date_second - $date_first ) < $seconds_limit_lastpost ) {
return $this->json( [
'message' => 'anti flood déclenché',
'details' => 'votre deriner commentaire a été envoyé il y a moins de ' . $seconds_limit_lastpost . ' secondes',
],
403 );
}
// check similar text content
if ( $lastCommentOfOwner[ 0 ]->getText() == $comment->getText() ) {
return $this->json( [
'message' => 'anti flood déclenché',
'details' => 'votre deriner commentaire a exactement le même contenu que celui ci, il n\'a donc pas été créé',
],
403 );
}
}
$comment->setOwner( $foundOwner )
->setCreatedAt( new DateTime() )
->setPoll( $poll );
$foundOwner->addComment( $comment );
$em = $this->getDoctrine()->getManager();
$em->persist( $foundOwner );
$em->persist( $comment );
$em->flush();
if ( $poll->getMailOnComment() ) {
$this->sendCommentNotificationAction( $foundOwner, $comment );
}
return $this->json( [ 201);
'message' => 'you created a comment',
'data' => [
'your_comment' => $comment->display(),
],
],
201 );
}
/** }
* Erase all comments of a poll
* @Delete(
* path = "/poll/{id}",
* name = "poll_comments_delete",
* requirements = {"accessToken"="\w+", "id"="\d+"}
* )
*
* @param Poll $poll
* @param $accessToken
*
* @return JsonResponse
*/
public
function deletePollCommentsAction(
Poll $poll,
$accessToken
) {
if ( $accessToken == $poll->getAdminKey() ) {
$em = $this->getDoctrine()->getManager();
$length = count( $poll->getComments() );
$em->remove( $poll->getComments() );
$em->flush();
return $this->json( [ /**
'message' => 'boom! les ' . $length . ' commentaires du sondage ont été supprimés', * add a comment on a poll
] ); * @Route(
} else { * "/poll/{customUrl}/by-owner",
return $this->json( [ * "_new_comment_by_owner",
'message' => 'le token d\'autorisation est invalide, vous ne pouvez pas modifier ce sondage', * methods={"POST"}
] ); * )
} */
} public
function newCommentByOwnerAction(
Poll $poll,
Request $request
)
{
if (!$poll) {
return $this->json(['message' => 'poll not found'], 404);
}
$data = $request->getContent();
$serializer = SerializerBuilder::create()->build();
$comment = $serializer->deserialize($data, 'App\Entity\Comment', 'json');
$em = $this->getDoctrine()->getRepository(Owner::class);
$data = json_decode($data, true);
if (!isset($data['email'])) {
return $this->json(["message" => "Incorrect JSON in request"], 400);
}
$foundOwner = $em->findOneByEmail($data['email']);
// manage existing or new Owner
if (!$foundOwner) {
$foundOwner = new Owner();
$foundOwner->setPseudo($data['pseudo'])
->setEmail($data['email'])
->setModifierToken(uniqid('', true));
}
// anti flood
$seconds_limit_lastpost = 5;
$emComment = $this->getDoctrine()->getRepository(Comment::class);
$lastCommentOfOwner = $emComment->findBy(['owner' => $foundOwner], ['id' => 'desc']);
// TODO anti flood by session / IP
if ($lastCommentOfOwner) {
// check time of last comment
$now = new DateTime();
$now = $now->format('Y-m-d H:i:s');
$date_first = strtotime($lastCommentOfOwner[0]->getCreatedAt()->format('Y-m-d H:i:s'));
$date_second = strtotime($now);
if (($date_second - $date_first) < $seconds_limit_lastpost) {
return $this->json([
'message' => 'anti flood déclenché',
'details' => 'votre deriner commentaire a été envoyé il y a moins de ' . $seconds_limit_lastpost . ' secondes',
],
403);
}
// check similar text content
if ($lastCommentOfOwner[0]->getText() == $comment->getText()) {
return $this->json([
'message' => 'anti flood déclenché',
'details' => 'votre deriner commentaire a exactement le même contenu que celui ci, il n\'a donc pas été créé',
],
403);
}
}
$comment->setOwner($foundOwner)
->setCreatedAt(new DateTime())
->setPoll($poll);
$foundOwner->addComment($comment);
$em = $this->getDoctrine()->getManager();
$em->persist($foundOwner);
$em->persist($comment);
$em->flush();
if ($poll->getMailOnComment()) {
$this->sendCommentNotificationAction($foundOwner, $comment);
}
return $this->json([
'message' => 'you created a comment',
'data' => [
'your_comment' => $comment->display(),
],
],
201);
}
/**
* Erase all comments of a poll
* @Delete(
* path = "/poll/{customUrl}",
* name = "poll_comments_delete"
* )
*
* @param Poll $poll
* @param $accessToken
*
* @return JsonResponse
*/
public
function deletePollCommentsAction(
Poll $poll,
$accessToken
)
{
if ($accessToken == $poll->getAdminKey()) {
$em = $this->getDoctrine()->getManager();
$length = count($poll->getComments());
$em->remove($poll->getComments());
$em->flush();
return $this->json([
'message' => 'boom! les ' . $length . ' commentaires du sondage ont été supprimés',
]);
} else {
return $this->json([
'message' => 'le token d\'autorisation est invalide, vous ne pouvez pas modifier ce sondage',
]);
}
}
} }

View File

@ -295,7 +295,7 @@ class PollController extends EmailsController
/** /**
* @Route( * @Route(
* "/", * "/",
* "_new_poll", * "_new_poll_v1",
* methods={"POST"} * methods={"POST"}
* ) * )
* @param Request $request * @param Request $request