<?php
namespace CodersLab\Lms\UserInterface\Rest\Controller;
use CodersLab\Lms\Modules\IdentityAccess\Application\IContentAccessContext;
use CodersLab\Lms\Modules\IdentityAccess\Application\Query\ProgressQuery;
use CodersLab\Lms\Modules\IdentityAccess\Application\Query\UserAccessQuery;
use CodersLab\Lms\Modules\Materials\Application\Query\CourseQuery;
use CodersLab\Lms\Modules\Materials\Application\Service\Material\MaterialInstanceSlug\Slug;
use CodersLab\Lms\SharedKernel\Application\Response\LmsApiResponse;
use CodersLab\Lms\SharedKernel\Application\SecurityContext;
use CodersLab\Lms\SharedKernel\Common\Exception\AccessDeniedHttpException;
use CodersLab\Lms\SharedKernel\Domain\Courses\MemberType;
use CodersLab\Lms\SharedKernel\Domain\Identity\Uuid;
use JMS\Serializer\SerializationContext;
use JMS\Serializer\SerializerInterface;
use OpenApi\Annotations as OA;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* @OA\Tag(name="User menu")
*/
final class MenuController
{
private SecurityContext $security;
private IContentAccessContext $accessContext;
private CourseQuery $courseQuery;
private UserAccessQuery $userAccessQuery;
private SerializerInterface $serializer;
private ProgressQuery $progressQuery;
public function __construct(
SecurityContext $security,
IContentAccessContext $accessContext,
CourseQuery $courseQuery,
UserAccessQuery $userAccessQuery,
SerializerInterface $serializer,
ProgressQuery $progressQuery
) {
$this->security = $security;
$this->accessContext = $accessContext;
$this->courseQuery = $courseQuery;
$this->userAccessQuery = $userAccessQuery;
$this->serializer = $serializer;
$this->progressQuery = $progressQuery;
}
/**
* @Route(
* "/menu/{chapterId}/{instanceId}",
* name="user_menu_id",
* methods={"GET"},
* requirements={"chapterId"="[a-f0-9]{8}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{12}"}
* )
*
* @OA\Parameter(name="chapterId", in="path", @OA\Schema(type="string"), required=true)
* @OA\Parameter(name="instanceId", in="path", @OA\Schema(type="string"), required=true)
* @OA\Response(response=200, description="")
*
*/
public function menuByChapterId(): Response
{
return new Response(null, Response::HTTP_MOVED_PERMANENTLY);
}
/**
* @Route(
* "/menu/{slug}/{instanceId}",
* name="user_menu_slug",
* methods={"GET"},
* requirements={"slug"="[0-9]+\-[0-9]+"}
* )
*
* @OA\Parameter(name="chapterId", in="path", @OA\Schema(type="string"), required=true)
* @OA\Parameter(name="instanceId", in="path", @OA\Schema(type="string"), required=true)
* @OA\Response(response=200, description="")
*
*/
public function menuBySlug(string $slug, string $instanceId): Response
{
$user = $this->security->getLoggedUser();
$memberTypes = $this->accessContext->getUserCourseInstanceRoles($user->id(), $instanceId);
$course = $this->courseQuery->getByInstanceId($instanceId, true, MemberType::chooseHighest($memberTypes));
if (!$this->accessContext->hasAccessToCourseInstance($user->id(), (int)$instanceId)) {
throw new AccessDeniedHttpException();
}
$course->addProgress($this->progressQuery->forCourseInstance(
(string)$instanceId,
(string)$this->security->getLoggedUser()->id()
));
$course->setAccess(
$this->userAccessQuery->findChaptersAccessOnCourse(
(string)$instanceId,
(string)$user->id()
)
);
$module = $course->getModuleBySlug(Slug::createFromString($slug));
$context = SerializationContext::create()->setSerializeNull(true);
$context->setGroups(['module', 'Default']);
return LmsApiResponse::createFromJsonString($this->serializer->serialize(
['data' => $module],
'json',
$context
));
}
/**
* @Route("/direct-access/menu/{chapterId}", name="user_menu_direct_access", methods={"GET"})
*
* @OA\Parameter(name="chapterId", in="path", @OA\Schema(type="string"), required=true)
* @OA\Parameter(name="instanceId", in="path", @OA\Schema(type="string"), required=true)
* @OA\Response(response=200, description="")
*
*/
public function menuDirectAccess(string $chapterId): Response
{
$user = $this->security->getLoggedUser();
$this->accessContext->hasDirectAccessByChapter((string)$user->id(), $chapterId);
$course = $this->courseQuery->getById((string)$this->courseQuery->findCourseIdForChapter($chapterId), true);
$module = $course->getModuleByChapter(new Uuid($chapterId));
$context = SerializationContext::create()->setSerializeNull(true);
$context->setGroups(['direct', 'Default']);
return LmsApiResponse::createFromJsonString($this->serializer->serialize(
['data' => $module],
'json',
$context
));
}
}