diff --git a/src/Bundle/ChillMainBundle/Controller/NotificationApiController.php b/src/Bundle/ChillMainBundle/Controller/NotificationApiController.php new file mode 100644 index 000000000..8751aa50a --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/NotificationApiController.php @@ -0,0 +1,87 @@ +entityManager = $entityManager; + $this->security = $security; + } + + /** + * @Route("/{id}/mark/read", name="chill_api_main_notification_mark_read", methods={"POST"}) + */ + public function markAsRead(Notification $notification): JsonResponse + { + return $this->markAs('read', $notification); + } + + /** + * @Route("/{id}/mark/unread", name="chill_api_main_notification_mark_unread", methods={"POST"}) + */ + public function markAsUnread(Notification $notification): JsonResponse + { + return $this->markAs('unread', $notification); + } + + private function markAs(string $target, Notification $notification): JsonResponse + { + if (!$this->security->isGranted(NotificationVoter::NOTIFICATION_TOGGLE_READ_STATUS, $notification)) { + throw new AccessDeniedException('Not allowed to toggle read status of notification'); + } + + $user = $this->security->getUser(); + + if (!$user instanceof User) { + throw new RuntimeException('not possible to mark as read by this user'); + } + + switch ($target) { + case 'read': + $notification->markAsReadBy($user); + + break; + + case 'unread': + $notification->markAsUnreadBy($user); + + break; + + default: + throw new UnexpectedValueException("target not supported: {$target}"); + } + + $this->entityManager->flush(); + + return new JsonResponse(null, JsonResponse::HTTP_ACCEPTED, [], false); + } +} diff --git a/src/Bundle/ChillMainBundle/Controller/NotificationController.php b/src/Bundle/ChillMainBundle/Controller/NotificationController.php index be6b60492..dddaf306f 100644 --- a/src/Bundle/ChillMainBundle/Controller/NotificationController.php +++ b/src/Bundle/ChillMainBundle/Controller/NotificationController.php @@ -125,7 +125,7 @@ class NotificationController extends AbstractController */ public function editAction(Notification $notification, Request $request): Response { - $this->denyAccessUnlessGranted(NotificationVoter::UPDATE, $notification); + $this->denyAccessUnlessGranted(NotificationVoter::NOTIFICATION_UPDATE, $notification); $form = $this->createForm(NotificationType::class, $notification); @@ -207,27 +207,61 @@ class NotificationController extends AbstractController */ public function showAction(Notification $notification, Request $request): Response { - $this->denyAccessUnlessGranted(NotificationVoter::SEE, $notification); + $this->denyAccessUnlessGranted(NotificationVoter::NOTIFICATION_SEE, $notification); - $notification->addComment($appendComment = new NotificationComment()); + $appendComment = new NotificationComment(); $appendCommentForm = $this->createForm(NotificationCommentType::class, $appendComment); - $appendCommentForm->handleRequest($request); - if ($appendCommentForm->isSubmitted() && $appendCommentForm->isValid()) { - $this->em->persist($appendComment); - $this->em->flush(); + if ($request->query->has('edit')) { + $commentId = $request->query->getInt('edit'); + $editedComment = $notification->getComments()->filter(static function (NotificationComment $c) use ($commentId) { + return $c->getId() === $commentId; + })->first(); - $this->addFlash('success', $this->translator->trans('notification.comment_appended')); + if (false === $editedComment) { + throw $this->createNotFoundException("Comment with id {$commentId} does not exists nor belong to this notification"); + } - return $this->redirectToRoute('chill_main_notification_show', [ - 'id' => $notification->getId(), - ]); + $editedCommentForm = $this->createForm(NotificationCommentType::class, $editedComment); + + if (Request::METHOD_POST === $request->getMethod() && 'edit' === $request->request->get('form')) { + $editedCommentForm->handleRequest($request); + + if ($editedCommentForm->isSubmitted() && $editedCommentForm->isValid()) { + $this->em->flush(); + + $this->addFlash('success', $this->translator->trans('notification.comment_updated')); + + return $this->redirectToRoute('chill_main_notification_show', [ + 'id' => $notification->getId(), + '_fragment' => 'comment-' . $commentId, + ]); + } + } + } + + if (Request::METHOD_POST === $request->getMethod() && 'append' === $request->request->get('form')) { + $appendCommentForm->handleRequest($request); + + if ($appendCommentForm->isSubmitted() && $appendCommentForm->isValid()) { + $notification->addComment($appendComment); + $this->em->persist($appendComment); + $this->em->flush(); + + $this->addFlash('success', $this->translator->trans('notification.comment_appended')); + + return $this->redirectToRoute('chill_main_notification_show', [ + 'id' => $notification->getId(), + ]); + } } $response = $this->render('@ChillMain/Notification/show.html.twig', [ 'notification' => $notification, 'handler' => $this->notificationHandlerManager->getHandler($notification), 'appendCommentForm' => $appendCommentForm->createView(), + 'editedCommentForm' => isset($editedCommentForm) ? $editedCommentForm->createView() : null, + 'editedCommentId' => $commentId ?? null, ]); // we mark the notification as read after having computed the response diff --git a/src/Bundle/ChillMainBundle/Resources/views/Notification/show.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Notification/show.html.twig index 9dd1c7cf6..86fafd031 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Notification/show.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Notification/show.html.twig @@ -18,7 +18,9 @@ {% if notification.comments|length > 0 %} {% for comment in notification.comments %} + {% if editedCommentForm is null or editedCommentId != comment.id %}
{{ comment.content|chill_markdown_to_html }}@@ -26,11 +28,30 @@ {% if is_granted('CHILL_MAIN_NOTIFICATION_COMMENT_EDIT', comment) %} {% endif %}