<?php
namespace App\Controller\Front\Scholar\Chapter;
use App\Entity\Account\User;
use App\Entity\Achievement\AchievedChapter;
use App\Entity\Achievement\AchievementTimeLog;
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 App\Service\Forum\MessageManager;
use App\Service\Scholar\LessonService;
use Nellapp\Bundle\SDKBundle\Permission\Enum\ChannelUserTrainingPermissionEnum;
use App\Form\Forum\MessageAnswerType;
use App\Form\Forum\MessageType;
use App\Repository\Forum\ChapterMessageRepository;
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 ChapterMessageRepository $messageRepository,
private EntityManagerInterface $em,
private NotificationManager $notificationManager,
private AchievementManager $achievementManager,
private MessageManager $messageManager,
private LessonService $lessonService,
)
{
}
#[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();
/** @var AchievedChapter $achievedChapter */
$achievedChapter = $this->achievementManager->getOrCreate($user, $chapter);
if ($achievedChapter) {
$achievementTimeLog = new AchievementTimeLog();
$achievementTimeLog->setAchievedChapter($achievedChapter)
->setChapter($chapter)
->setLesson($lesson)
->setModule($module)
->setTraining($training)
->setStartAt(new \DateTime());
$this->em->persist($achievementTimeLog);
$this->em->flush();
}
/**
* Form for a message which is a new one
*/
$message = $this->messageManager->createUserChapterMessage($user, $chapter, $module, $training);
$form = $this->createForm(MessageType::class, $message);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$message->setAssignedTo($this->lessonService->getLessonReferralTrainer($lesson));
// 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 ChapterMessage $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 && null !== ($messageUser = $messageParent->getUser())) {
$this->notificationManager->addChapterResponseMessageNotification(
$messageUser,
$user,
$message->getChapter(),
$message,
$training->getId(),
$module->getId(),
$lesson->getId()
);
} else {
$this->notificationManager->addMessageNotificationToStaff($user, $chapter, $message, $module, $training);
}
}
}
/**
* Form for a message which answer a question
*/
$messageAnswer = $this->messageManager->createUserChapterMessage($user, $chapter, $module, $training);
$formAnswerQuestion = $this->createForm(MessageAnswerType::class, $messageAnswer);
$formAnswerQuestion->handleRequest($request);
if ($formAnswerQuestion->isSubmitted() && $formAnswerQuestion->isValid()) {
$messageAnswer->setAssignableStatus(0);
$messageAnswer->setAssignedTo($this->lessonService->getLessonReferralTrainer($lesson));
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 ($user) {
if ($formAnswerQuestion->get('parent-id')->getData() !== null && null !== ($messageUser = $messageParent->getUser())) {
$this->notificationManager->addChapterResponseMessageNotification(
$messageUser,
$user,
$messageAnswer->getChapter(),
$messageAnswer,
$training->getId(),
$module->getId(),
$lesson->getId()
);
} else {
$this->notificationManager->addMessageNotificationToStaff($user, $chapter, $messageAnswer, $module, $training);
}
}
}
$messages = $this->messageRepository->findByChapter($chapter);
$isGrantedComment = false;
if ($user !== null) {
$isGrantedComment = $this->isGranted(ChannelUserTrainingPermissionEnum::CHANNEL_USER_PERM_TRAINING_MANAGE_COMMENT, $module);
}
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(),
]);
}
}