From ebbe670508c650eb5675d6e897dedb0e384692c3 Mon Sep 17 00:00:00 2001 From: Matis MAZINGUE Date: Thu, 13 Jun 2024 09:42:26 +0200 Subject: [PATCH 1/6] add like in entity Post --- src/Entity/Post.php | 31 +++++++++++++++++++++++++++++++ src/Entity/User.php | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/src/Entity/Post.php b/src/Entity/Post.php index fa0217a..b8b0046 100644 --- a/src/Entity/Post.php +++ b/src/Entity/Post.php @@ -84,9 +84,16 @@ class Post #[ORM\OneToMany(targetEntity: Comment::class, mappedBy: 'related_post', fetch: 'EXTRA_LAZY')] private Collection $comments; + /** + * @var Collection + */ + #[ORM\ManyToMany(targetEntity: User::class, inversedBy: 'liked_post')] + private Collection $likes; + public function __construct() { $this->comments = new ArrayCollection(); + $this->likes = new ArrayCollection(); } public function getId(): ?int @@ -256,4 +263,28 @@ class Post return $this; } + + /** + * @return Collection + */ + public function getLikes(): Collection + { + return $this->likes; + } + + public function addLike(User $user): static + { + if (!$this->likes->contains($user)) { + $this->likes->add($user); + } + + return $this; + } + + public function removeLike(User $user): static + { + $this->likes->removeElement($user); + + return $this; + } } diff --git a/src/Entity/User.php b/src/Entity/User.php index 8519d9d..81a6b3a 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -68,9 +68,16 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\OneToMany(targetEntity: Comment::class, mappedBy: 'author')] private Collection $comments; + /** + * @var Collection + */ + #[ORM\ManyToMany(targetEntity: Post::class, mappedBy: 'likes')] + private Collection $liked_post; + public function __construct() { $this->comments = new ArrayCollection(); + $this->liked_post = new ArrayCollection(); } public function getId(): ?int @@ -189,4 +196,31 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface return $this; } + + /** + * @return Collection + */ + public function getLikedPost(): Collection + { + return $this->liked_post; + } + + public function addLikedPost(Post $likedPost): static + { + if (!$this->liked_post->contains($likedPost)) { + $this->liked_post->add($likedPost); + $likedPost->addLike($this); + } + + return $this; + } + + public function removeLikedPost(Post $likedPost): static + { + if ($this->liked_post->removeElement($likedPost)) { + $likedPost->removeLike($this); + } + + return $this; + } } -- 2.36.3 From 8d1f0b9a6f468ef0a72eeef49ec1a02793b52c63 Mon Sep 17 00:00:00 2001 From: Matis MAZINGUE Date: Thu, 13 Jun 2024 09:53:07 +0200 Subject: [PATCH 2/6] Like a post --- src/Controller/PostController.php | 20 ++++++++++++++++++++ templates/post/index.html.twig | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Controller/PostController.php b/src/Controller/PostController.php index 7f4e77f..0020574 100644 --- a/src/Controller/PostController.php +++ b/src/Controller/PostController.php @@ -170,4 +170,24 @@ class PostController extends AbstractController } return $this->redirectToRoute('app_post_show', ['id' => $comment->getRelatedPost()->getId()]); } + + #[Route('/post/{id}/like', name: 'app_posts', methods: ['POST'])] + #[IsGranted('ROLE_USER')] + public function addLike(Request $request, Post $post, EntityManagerInterface $entityManager, #[CurrentUser] User $user): Response + { + $user->addLikedPost($post); + $entityManager->flush(); + return $this->redirectToRoute('app_post_show', ['id' => $post->getId()], Response::HTTP_SEE_OTHER); + } + + #[Route('/post/{id}/unlike', name: 'app_posts', methods: ['POST'])] + #[IsGranted('ROLE_USER')] + public function deleteLike(Request $request, Post $post, EntityManagerInterface $entityManager, #[CurrentUser] User $user): Response + { + $user->removeLikedPost($post); + $entityManager->flush(); + return $this->redirectToRoute('app_post_show', ['id' => $post->getId()], Response::HTTP_SEE_OTHER); + + } + } diff --git a/templates/post/index.html.twig b/templates/post/index.html.twig index d14adbc..2b404bd 100644 --- a/templates/post/index.html.twig +++ b/templates/post/index.html.twig @@ -12,7 +12,7 @@

{{ post.commentary }}

-- 2.36.3 From c8617388c7fec5fabf8181bedf3fb72028433037 Mon Sep 17 00:00:00 2001 From: Matis MAZINGUE Date: Thu, 13 Jun 2024 11:54:28 +0200 Subject: [PATCH 3/6] =?UTF-8?q?fonctionnalit=C3=A9=20like=20and=20dislike?= =?UTF-8?q?=20of=20a=20post?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/css/app.css | 12 +++++++++++ public/js/like_toggle.js | 36 +++++++++++++++++++++++++++++++ src/Controller/PostController.php | 35 ++++++++++++++++++++++++------ templates/base.html.twig | 1 + templates/post/index.html.twig | 17 ++++++++++++++- 5 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 public/css/app.css create mode 100644 public/js/like_toggle.js diff --git a/public/css/app.css b/public/css/app.css new file mode 100644 index 0000000..5da752c --- /dev/null +++ b/public/css/app.css @@ -0,0 +1,12 @@ +.no-style { + background: none; + border: none; + padding: 0; + font: inherit; + color: inherit; + cursor: pointer; +} + +.no-style:focus { + outline: none; +} diff --git a/public/js/like_toggle.js b/public/js/like_toggle.js new file mode 100644 index 0000000..3334629 --- /dev/null +++ b/public/js/like_toggle.js @@ -0,0 +1,36 @@ +document.addEventListener('DOMContentLoaded', function() { + document.querySelectorAll('.like-toggle').forEach(button => { + button.addEventListener('click', function(event) { + event.preventDefault(); + + let postId = this.dataset.postId; + let isLiked = this.classList.contains('liked'); + let url = isLiked ? this.dataset.unlikeUrl : this.dataset.likeUrl; + + fetch(url, { method: 'POST' }) + .then(response => response.json()) + .then(data => { + if (data.success) { + let likesCountElement = this.parentElement.querySelector('.likes-count'); + let likesCount = parseInt(likesCountElement.textContent); + + if (isLiked) { + likesCount--; + } else { + likesCount++; + } + + likesCountElement.textContent = likesCount; + this.classList.toggle('liked'); + this.classList.toggle('not-liked'); + this.innerHTML = isLiked ? '♡' : '❤️'; + } else { + console.error('Erreur lors du traitement du like/unlike.'); + } + }) + .catch(error => { + console.error('Erreur lors de la requête fetch:', error); + }); + }); + }); +}); diff --git a/src/Controller/PostController.php b/src/Controller/PostController.php index 0020574..8a6c012 100644 --- a/src/Controller/PostController.php +++ b/src/Controller/PostController.php @@ -16,6 +16,7 @@ use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\CurrentUser; use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\UX\Turbo\TurboBundle; +use Symfony\Component\HttpFoundation\JsonResponse; class PostController extends AbstractController { @@ -171,23 +172,45 @@ class PostController extends AbstractController return $this->redirectToRoute('app_post_show', ['id' => $comment->getRelatedPost()->getId()]); } - #[Route('/post/{id}/like', name: 'app_posts', methods: ['POST'])] + // #[Route('/post/{id}/like', name: 'app_posts_like', methods: ['POST'])] + // #[IsGranted('ROLE_USER')] + // public function addLike(Post $post, EntityManagerInterface $entityManager, #[CurrentUser] User $user): Response + // { + // $user->addLikedPost($post); + // $entityManager->flush(); + // return $this->redirectToRoute('app_post_show', ['id' => $post->getId()], Response::HTTP_SEE_OTHER); + // } + + // #[Route('/post/{id}/unlike', name: 'app_posts_unlike', methods: ['POST'])] + // #[IsGranted('ROLE_USER')] + // public function deleteLike(Post $post, EntityManagerInterface $entityManager, #[CurrentUser] User $user): Response + // { + // $user->removeLikedPost($post); + // $entityManager->flush(); + // return $this->redirectToRoute('app_post_show', ['id' => $post->getId()], Response::HTTP_SEE_OTHER); + // } + #[Route('/post/{id}/like', name: 'app_posts_like', methods: ['POST'])] #[IsGranted('ROLE_USER')] - public function addLike(Request $request, Post $post, EntityManagerInterface $entityManager, #[CurrentUser] User $user): Response + public function addLike(#[CurrentUser] User $user, Post $post, EntityManagerInterface $entityManager): JsonResponse { $user->addLikedPost($post); $entityManager->flush(); - return $this->redirectToRoute('app_post_show', ['id' => $post->getId()], Response::HTTP_SEE_OTHER); + + $likesCount = $post->getLikes()->count(); + + return new JsonResponse(['success' => true, 'likesCount' => $likesCount]); } - #[Route('/post/{id}/unlike', name: 'app_posts', methods: ['POST'])] + #[Route('/post/{id}/unlike', name: 'app_posts_unlike', methods: ['POST'])] #[IsGranted('ROLE_USER')] - public function deleteLike(Request $request, Post $post, EntityManagerInterface $entityManager, #[CurrentUser] User $user): Response + public function deleteLike(#[CurrentUser] User $user, Post $post, EntityManagerInterface $entityManager): JsonResponse { $user->removeLikedPost($post); $entityManager->flush(); - return $this->redirectToRoute('app_post_show', ['id' => $post->getId()], Response::HTTP_SEE_OTHER); + $likesCount = $post->getLikes()->count(); + + return new JsonResponse(['success' => true, 'likesCount' => $likesCount]); } } diff --git a/templates/base.html.twig b/templates/base.html.twig index 0ced7a9..903f586 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -6,6 +6,7 @@ {% block stylesheets %} + {% endblock %} {% block javascripts %} diff --git a/templates/post/index.html.twig b/templates/post/index.html.twig index 2b404bd..20fc847 100644 --- a/templates/post/index.html.twig +++ b/templates/post/index.html.twig @@ -12,10 +12,25 @@

{{ post.commentary }}

{% endfor %} {% include '_pagination.html.twig' %} {% endblock %} + +{% block javascripts %} + {{ parent() }} + +{% endblock %} -- 2.36.3 From 2e20f5610e7816072999bffbf8cbcb6e1fd55a17 Mon Sep 17 00:00:00 2001 From: Matis MAZINGUE Date: Thu, 13 Jun 2024 11:54:56 +0200 Subject: [PATCH 4/6] postController --- src/Controller/PostController.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/Controller/PostController.php b/src/Controller/PostController.php index 8a6c012..5be66b8 100644 --- a/src/Controller/PostController.php +++ b/src/Controller/PostController.php @@ -172,23 +172,6 @@ class PostController extends AbstractController return $this->redirectToRoute('app_post_show', ['id' => $comment->getRelatedPost()->getId()]); } - // #[Route('/post/{id}/like', name: 'app_posts_like', methods: ['POST'])] - // #[IsGranted('ROLE_USER')] - // public function addLike(Post $post, EntityManagerInterface $entityManager, #[CurrentUser] User $user): Response - // { - // $user->addLikedPost($post); - // $entityManager->flush(); - // return $this->redirectToRoute('app_post_show', ['id' => $post->getId()], Response::HTTP_SEE_OTHER); - // } - - // #[Route('/post/{id}/unlike', name: 'app_posts_unlike', methods: ['POST'])] - // #[IsGranted('ROLE_USER')] - // public function deleteLike(Post $post, EntityManagerInterface $entityManager, #[CurrentUser] User $user): Response - // { - // $user->removeLikedPost($post); - // $entityManager->flush(); - // return $this->redirectToRoute('app_post_show', ['id' => $post->getId()], Response::HTTP_SEE_OTHER); - // } #[Route('/post/{id}/like', name: 'app_posts_like', methods: ['POST'])] #[IsGranted('ROLE_USER')] public function addLike(#[CurrentUser] User $user, Post $post, EntityManagerInterface $entityManager): JsonResponse -- 2.36.3 From cab499d1adf3f67fa632a22dce4b62031d3d1b37 Mon Sep 17 00:00:00 2001 From: clfreville2 Date: Fri, 14 Jun 2024 09:35:32 +0200 Subject: [PATCH 5/6] Remove unused values --- public/js/like_toggle.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/public/js/like_toggle.js b/public/js/like_toggle.js index 3334629..b2a9168 100644 --- a/public/js/like_toggle.js +++ b/public/js/like_toggle.js @@ -1,9 +1,8 @@ document.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('.like-toggle').forEach(button => { - button.addEventListener('click', function(event) { + button.addEventListener('click', function (event) { event.preventDefault(); - let postId = this.dataset.postId; let isLiked = this.classList.contains('liked'); let url = isLiked ? this.dataset.unlikeUrl : this.dataset.likeUrl; @@ -20,7 +19,7 @@ document.addEventListener('DOMContentLoaded', function() { likesCount++; } - likesCountElement.textContent = likesCount; + likesCountElement.textContent = likesCount.toString(); this.classList.toggle('liked'); this.classList.toggle('not-liked'); this.innerHTML = isLiked ? '♡' : '❤️'; -- 2.36.3 From 481c09e2da4b854b8627aaf9541c4bb2fc29811e Mon Sep 17 00:00:00 2001 From: clfreville2 Date: Fri, 14 Jun 2024 09:40:16 +0200 Subject: [PATCH 6/6] Use count from the request response --- public/js/like_toggle.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/public/js/like_toggle.js b/public/js/like_toggle.js index b2a9168..1f89096 100644 --- a/public/js/like_toggle.js +++ b/public/js/like_toggle.js @@ -11,15 +11,7 @@ document.addEventListener('DOMContentLoaded', function() { .then(data => { if (data.success) { let likesCountElement = this.parentElement.querySelector('.likes-count'); - let likesCount = parseInt(likesCountElement.textContent); - - if (isLiked) { - likesCount--; - } else { - likesCount++; - } - - likesCountElement.textContent = likesCount.toString(); + likesCountElement.textContent = data.likesCount; this.classList.toggle('liked'); this.classList.toggle('not-liked'); this.innerHTML = isLiked ? '♡' : '❤️'; -- 2.36.3