<?php
namespace App\Controller\Front\Scholar\Chapter;
use App\Entity\Account\User;
use App\Entity\Forum\Message;
use App\Entity\Scholar\Chapter\Chapter;
use App\Entity\Scholar\Lesson\Lesson;
use App\Entity\Scholar\Module\Module;
use App\Entity\Scholar\Training\Training;
use App\Enum\AssignableStatusEnum;
use Nellapp\Bundle\SDKBundle\Permission\Enum\ChannelUserPermissionEnum;
use Nellapp\Bundle\SDKBundle\Permission\Enum\ChannelUserTrainingPermissionEnum;
use App\Form\Forum\MessageAnswerType;
use App\Form\Forum\MessageType;
use App\Repository\Forum\MessageRepository;
use App\Service\Account\NotificationManager;
use App\Service\Achievement\AchievementManager;
use App\Service\Scholar\StatusService;
use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
class ChapterController extends AbstractController
{
public function __construct(
private MessageRepository $messageRepository,
private EntityManagerInterface $em,
private NotificationManager $notificationManager,
private AchievementManager $achievementManager,
) {}
#[Route(path: '/training/{trainingId}/module/{moduleId}/lesson/{lessonId}/chapter/{chapterId}', name: 'front_channel_chapter_show')]
#[ParamConverter('training', options: ['id' => 'trainingId'])]
#[ParamConverter('module', options: ['id' => 'moduleId'])]
#[ParamConverter('lesson', options: ['id' => 'lessonId'])]
#[ParamConverter('chapter', options: ['id' => 'chapterId'])]
public function __invoke(Request $request, Training $training, Module $module, Lesson $lesson, Chapter $chapter, StatusService $statusService): Response
{
if (!$this->isGranted('FRONT_ACCESS', [
'training' => $training,
'module' => $module,
'lesson' => $lesson,
])) {
throw $this->createAccessDeniedException();
}
if ($chapter->getLesson() !== $lesson) {
throw new NotFoundHttpException();
}
/** @var ?User $user */
$user = $this->getUser();
$this->achievementManager->create($user, $chapter);
/**
* Form for a message which is a new one
*/
$message = new Message();
$form = $this->createForm(MessageType::class, $message);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$message->setUser($this->getUser());
$message
->setTraining($training)
->setModule($module)
->setChapter($chapter);
$message->setAssignedTo($lesson->getReferralTrainer());
// If the user that created the message is Manager -> DONE
if ($this->isGranted(ChannelUserTrainingPermissionEnum::CHANNEL_USER_PERM_TRAINING_MANAGE_COMMENT, $training)) {
$message->setAssignableStatus(AssignableStatusEnum::DONE);
} else {
$message->setAssignableStatus(AssignableStatusEnum::TODO);
}
if ($form->get('parent-id')->getData() !== null) {
$messageId = $form->get('parent-id')->getData();
$messageParent = $this->messageRepository->find($messageId);
$message->setParent($messageParent);
// If the user that created the message is the assignee of the message parent -> DONE
if ($this->getUser() && $messageParent->getAssignedTo() === $this->getUser()) {
$message->setAssignableStatus(AssignableStatusEnum::DONE);
}
// In case the user that created the message is the assignee of the parent message or Manager:
// MessageParent -> DONE
// All childs of message parent -> DONE
if ($this->isGranted(ChannelUserTrainingPermissionEnum::CHANNEL_USER_PERM_TRAINING_MANAGE_COMMENT, $training)
|| $this->getUser() && $messageParent->getAssignedTo() === $this->getUser()
) {
$messageParent->setAssignableStatus(AssignableStatusEnum::DONE);
$this->em->persist($messageParent);
/** @var Message $childMessage */
foreach ($messageParent->getChildren() as $childMessage) {
$childMessage->setAssignableStatus(AssignableStatusEnum::DONE);
$this->em->persist($childMessage);
}
}
}
$this->em->persist($message);
$this->em->flush();
if ($message->getAssignableStatus() === AssignableStatusEnum::TODO && $user) {
if ($form->get('parent-id')->getData() !== null) {
$this->notificationManager->addChapterResponseMessageNotification(
$messageParent->getUser(),
$user,
$message->getChapter(),
$message,
$training->getId(),
$module->getId(),
$lesson->getId()
);
} else {
$this->notificationManager->addMessageNotificationToStaff($user, $chapter, $message, $training->getId(), $module->getId(), $lesson->getId());
}
}
}
/**
* Form for a message which answer a question
*/
$messageAnswer = new Message();
$formAnswerQuestion = $this->createForm(MessageAnswerType::class, $messageAnswer);
$formAnswerQuestion->handleRequest($request);
if ($formAnswerQuestion->isSubmitted() && $formAnswerQuestion->isValid()) {
$messageAnswer->setUser($this->getUser());
$messageAnswer
->setTraining($training)
->setModule($module)
->setChapter($chapter);
$messageAnswer->setAssignableStatus(0);
$messageAnswer->setAssignedTo($lesson->getReferralTrainer());
if ($this->isGranted(ChannelUserTrainingPermissionEnum::CHANNEL_USER_PERM_TRAINING_MANAGE_COMMENT, $training)) {
$messageAnswer->setAssignableStatus(AssignableStatusEnum::DONE);
} else {
$messageAnswer->setAssignableStatus(AssignableStatusEnum::TODO);
}
if ($formAnswerQuestion->get('parent-id')->getData() !== null) {
$messageId = $formAnswerQuestion->get('parent-id')->getData();
$messageParent = $this->messageRepository->find($messageId);
$messageAnswer->setParent($messageParent);
if ($this->getUser() && $messageParent->getAssignedTo() === $this->getUser()) {
$messageAnswer->setAssignableStatus(AssignableStatusEnum::DONE);
}
if ($this->isGranted(ChannelUserTrainingPermissionEnum::CHANNEL_USER_PERM_TRAINING_MANAGE_COMMENT, $training)
|| $this->getUser() && $messageParent->getAssignedTo() === $this->getUser()
) {
$messageParent->setAssignableStatus(AssignableStatusEnum::DONE);
}
}
$this->em->persist($messageAnswer);
$this->em->flush();
if ($messageAnswer->getAssignableStatus() === AssignableStatusEnum::TODO && $user) {
if ($formAnswerQuestion->get('parent-id')->getData() !== null) {
$this->notificationManager->addChapterResponseMessageNotification(
$messageParent->getUser(),
$user,
$messageAnswer->getChapter(),
$messageAnswer,
$training->getId(),
$module->getId(),
$lesson->getId()
);
} else {
$this->notificationManager->addMessageNotificationToStaff($user, $chapter, $messageAnswer, $training->getId(), $module->getId(), $lesson->getId());
}
}
}
$messages = $this->messageRepository->findByChapter($chapter);
$isGrantedComment = false;
if ($user !== null) {
$isGrantedComment = $this->isGranted(ChannelUserTrainingPermissionEnum::CHANNEL_USER_PERM_TRAINING_MANAGE_COMMENT, $training);
}
return $this->render('Front/Scholar/Chapter/show.html.twig', [
'chapter' => $chapter,
'messages' => $messages,
'form' => $form->createView(),
'formAnswer' => $formAnswerQuestion->createView(),
'module' => $module,
'training' => $training,
'lesson' => $lesson,
'is_granted_comment' => $isGrantedComment,
'channel' => $training->getOwnerChannel()
]);
}
}