src/Lms/UserInterface/Rest/Controller/CourseInstanceController.php line 49

Open in your IDE?
  1. <?php
  2. namespace CodersLab\Lms\UserInterface\Rest\Controller;
  3. use CodersLab\Lms\Modules\Courses\Application\Query\CourseInstanceFilter;
  4. use CodersLab\Lms\Modules\Courses\Application\Query\CourseInstanceQuery;
  5. use CodersLab\Lms\Modules\IdentityAccess\Application\IContentAccessContext;
  6. use CodersLab\Lms\Modules\Learning\Application\Query\StudentQuery;
  7. use CodersLab\Lms\SharedKernel\Application\Response\CourseMetadata;
  8. use CodersLab\Lms\SharedKernel\Application\Response\LmsApiResponse;
  9. use CodersLab\Lms\SharedKernel\Application\Response\Metadata;
  10. use CodersLab\Lms\SharedKernel\Application\SecurityContext;
  11. use CodersLab\Lms\SharedKernel\Common\Exception\AccessDeniedHttpException;
  12. use CodersLab\Lms\SharedKernel\Common\Exception\BadRequestHttpException;
  13. use CodersLab\Lms\SharedKernel\Common\Exception\NotFoundException;
  14. use CodersLab\Lms\SharedKernel\Domain\Courses\MemberType;
  15. use JMS\Serializer\SerializationContext;
  16. use JMS\Serializer\SerializerInterface;
  17. use Nelmio\ApiDocBundle\Annotation\Model;
  18. use OpenApi\Annotations as OA;
  19. use Symfony\Component\HttpFoundation\JsonResponse;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\Routing\Annotation\Route;
  22. /**
  23.  * @OA\Tag(name="Course Instance")
  24.  */
  25. final class CourseInstanceController
  26. {
  27.     public function __construct(
  28.         private CourseInstanceQuery $courseInstanceQuery,
  29.         private StudentQuery $studentQuery,
  30.         private SecurityContext $securityContext,
  31.         private IContentAccessContext $accessContext,
  32.         private SerializerInterface $serializer
  33.     ) {
  34.     }
  35.     /**
  36.      * @Route("/course_instance", name="course_instance_details", methods={"GET"})
  37.      * @OA\Parameter(name="id", in="query", @OA\Schema(type="string"))
  38.      * @OA\Parameter(name="signature", in="query", @OA\Schema(type="string"))
  39.      * @OA\Response(
  40.      *     response=200,
  41.      *     description="Single course instance",
  42.      *     @OA\Schema(ref=@Model(type="CodersLab\Lms\Modules\Courses\Application\Query\Model\CourseInstance"))
  43.      * )
  44.      */
  45.     public function getSingle(Request $request): LmsApiResponse
  46.     {
  47.         $params $request->query->all();
  48.         if (!isset($params['id']) && !isset($params['signature'])) {
  49.             throw new BadRequestHttpException('Instance id or signature is required');
  50.         }
  51.         if (isset($params['id'])) {
  52.             $instance $this->courseInstanceQuery->getById((int)$params['id']);
  53.         } else {
  54.             $instance $this->courseInstanceQuery->getBySignature($params['signature']);
  55.         }
  56.         $instance->setAccess($this->courseInstanceQuery->getAccess(
  57.             (string)$instance->getId(),
  58.             $this->securityContext->getLoggedUserId()
  59.         ));
  60.         $user $this->securityContext->getLoggedUser();
  61.         $access $this->accessContext->hasAccessToCourseInstance(
  62.             $user->id(),
  63.             $instance->getId()
  64.         );
  65.         if (!$access) {
  66.             throw new AccessDeniedHttpException();
  67.         }
  68.         $metadata CourseMetadata::create($this->accessContext->getUserCourseInstanceRoles($user->id(), (string)$instance->getId()));
  69.         return new LmsApiResponse($instance$metadata);
  70.     }
  71.     /**
  72.      * @Route("/course_instances", name="course_instance_list", methods={"GET"})
  73.      * @OA\Parameter(name="signature", in="query", @OA\Schema(type="string"))
  74.      * @OA\Parameter(name="page", in="query", @OA\Schema(type="string"))
  75.      * @OA\Response(
  76.      *     response=200,
  77.      *     description="Single course instance",
  78.      *     @OA\JsonContent(
  79.      *         type="array",
  80.      *         @OA\Items(ref=@Model(type="CodersLab\Lms\Modules\Courses\Application\Query\Model\CourseInstance"))
  81.      *     )
  82.      * )
  83.      */
  84.     public function getList(Request $request): LmsApiResponse
  85.     {
  86.         $filter CourseInstanceFilter::fromRequest($request$this->securityContext->getLoggedUserId());
  87.         $data $this->courseInstanceQuery->find($filter);
  88.         $total $this->courseInstanceQuery->count($filter);
  89.         foreach ($data as $courseInstance) {
  90.             $roles $this->accessContext->getUserCourseInstanceRoles($this->securityContext->getLoggedUserId(), (string)$courseInstance->getId());
  91.             $courseInstance->setRoles($roles);
  92.         }
  93.         return new LmsApiResponse($dataMetadata::forList($filter->getFilter()->page(), $filter->getFilter()->limit(), $total));
  94.     }
  95.     /**
  96.      * @Route(
  97.      *     "/course_instance/{courseInstanceId}/students",
  98.      *     name="course_instance_students",
  99.      *     methods={"GET"},
  100.      *     requirements={"courseInstanceId"="\d+"}
  101.      * )
  102.      * @OA\Parameter(name="courseInstanceId", in="path", @OA\Schema(type="integer"))
  103.      * @OA\Response(
  104.      *     response=200,
  105.      *     description="Course instance students list",
  106.      *     @OA\JsonContent(
  107.      *         type="array",
  108.      *         @OA\Items(ref=@Model(type="CodersLab\Lms\Modules\Learning\Application\Query\Model\Student", groups={"InstanceStudents"}))
  109.      *     )
  110.      * )
  111.      *
  112.      */
  113.     public function getStudents(int $courseInstanceId): JsonResponse
  114.     {
  115.         try {
  116.             $courseInstance $this->courseInstanceQuery->getById($courseInstanceId);
  117.         } catch (NotFoundException $ex) {
  118.             throw new BadRequestHttpException($ex->getMessage());
  119.         }
  120.         $hasAccess $this->accessContext->hasAccessToCourseInstance(
  121.             $this->securityContext->getLoggedUser()->id(),
  122.             $courseInstance->getId(),
  123.             [MemberType::MENTOR()->getValue(), MemberType::LECTURER()->getValue()]
  124.         );
  125.         if ($hasAccess === false) {
  126.             throw new AccessDeniedHttpException('Only mentor and lecturer has access to course instance students list');
  127.         }
  128.         $students $this->studentQuery->findByCourseInstance($courseInstanceId);
  129.         $context SerializationContext::create();
  130.         $context->setGroups('InstanceStudents');
  131.         return LmsApiResponse::createFromJsonString(
  132.             $this->serializer->serialize(
  133.                 ['data' => $students'metadata' => []],
  134.                 'json',
  135.                 $context
  136.             )
  137.         );
  138.     }
  139.     /**
  140.      * @Route("/course-instance/{instanceId}/side-menu", name="instance_side_menu", methods={"GET"})
  141.      * @OA\Response(
  142.      *     response=200,
  143.      *     description="Course Instance side menu",
  144.      *     @OA\Schema(ref=@Model(type="CodersLab\Lms\Modules\Courses\Application\Query\Model\CourseInstance\CourseInstanceSideMenu"))
  145.      * )
  146.      */
  147.     public function sideMenu(string $instanceId): LmsApiResponse
  148.     {
  149.         // TODO remove with new UI
  150.         $courseInstance $this->courseInstanceQuery->getForSideMenu(
  151.             $instanceId,
  152.             (string)$this->securityContext->getLoggedUserId()
  153.         );
  154.         return LmsApiResponse::create($courseInstance->toArray());
  155.     }
  156. }