Passed
Push — master ( 2513d4...4ebd25 )
by Angel Fernando Quiroz
08:36
created

CourseController::isUserEnrolledInAnyCourse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 8
rs 10
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\Controller;
8
9
use Chamilo\CoreBundle\Entity\Course;
10
use Chamilo\CoreBundle\Entity\CourseRelUser;
11
use Chamilo\CoreBundle\Entity\ExtraField;
12
use Chamilo\CoreBundle\Entity\Session;
13
use Chamilo\CoreBundle\Entity\SessionRelUser;
14
use Chamilo\CoreBundle\Entity\Tag;
15
use Chamilo\CoreBundle\Entity\Tool;
16
use Chamilo\CoreBundle\Entity\User;
17
use Chamilo\CoreBundle\Framework\Container;
18
use Chamilo\CoreBundle\Repository\ExtraFieldValuesRepository;
19
use Chamilo\CoreBundle\Repository\LanguageRepository;
20
use Chamilo\CoreBundle\Repository\LegalRepository;
21
use Chamilo\CoreBundle\Repository\Node\IllustrationRepository;
22
use Chamilo\CoreBundle\Repository\TagRepository;
23
use Chamilo\CoreBundle\Security\Authorization\Voter\CourseVoter;
24
use Chamilo\CoreBundle\Settings\SettingsManager;
25
use Chamilo\CoreBundle\Tool\AbstractTool;
26
use Chamilo\CoreBundle\Tool\ToolChain;
27
use Chamilo\CourseBundle\Controller\ToolBaseController;
28
use Chamilo\CourseBundle\Entity\CCourseDescription;
29
use Chamilo\CourseBundle\Entity\CTool;
30
use Chamilo\CourseBundle\Entity\CToolIntro;
31
use Chamilo\CourseBundle\Repository\CCourseDescriptionRepository;
32
use Chamilo\CourseBundle\Repository\CShortcutRepository;
33
use Chamilo\CourseBundle\Repository\CToolRepository;
34
use Chamilo\CourseBundle\Settings\SettingsCourseManager;
35
use Chamilo\CourseBundle\Settings\SettingsFormFactory;
36
use CourseManager;
37
use Database;
38
use Display;
39
use Doctrine\ORM\EntityManagerInterface;
40
use Event;
41
use Exercise;
42
use ExtraFieldValue;
43
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
44
use Symfony\Component\HttpFoundation\JsonResponse;
45
use Symfony\Component\HttpFoundation\RedirectResponse;
46
use Symfony\Component\HttpFoundation\Request;
47
use Symfony\Component\HttpFoundation\Response;
48
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
49
use Symfony\Component\Routing\Annotation\Route;
50
use Symfony\Component\Serializer\SerializerInterface;
51
use Symfony\Component\Validator\Exception\ValidatorException;
52
use UserManager;
53
54
/**
55
 * @author Julio Montoya <[email protected]>
56
 */
57
#[Route('/course')]
58
class CourseController extends ToolBaseController
59
{
60
    public function __construct(
61
        private readonly EntityManagerInterface $em,
62
        private readonly SerializerInterface $serializer
63
    ) {}
64
65
    #[Route('/{cid}/checkLegal.json', name: 'chamilo_core_course_check_legal_json')]
66
    public function checkTermsAndConditionJson(
67
        Request $request,
68
        LegalRepository $legalTermsRepo,
69
        LanguageRepository $languageRepository,
70
        ExtraFieldValuesRepository $extraFieldValuesRepository,
71
        SettingsManager $settingsManager
72
    ): Response {
73
        /** @var User $user */
74
        $user = $this->getUser();
75
        $course = $this->getCourse();
76
        $responseData = [
77
            'redirect' => false,
78
            'url' => '#',
79
        ];
80
81
        if ($user && $user->hasRole('ROLE_STUDENT')
82
            && 'true' === $settingsManager->getSetting('allow_terms_conditions')
83
            && 'course' === $settingsManager->getSetting('load_term_conditions_section')
84
        ) {
85
            $termAndConditionStatus = false;
86
            $extraValue = $extraFieldValuesRepository->findLegalAcceptByItemId($user->getId());
87
            if (!empty($extraValue['value'])) {
88
                $result = $extraValue['value'];
89
                $userConditions = explode(':', $result);
90
                $version = $userConditions[0];
91
                $langId = (int) $userConditions[1];
92
                $realVersion = $legalTermsRepo->getLastVersion($langId);
93
                $termAndConditionStatus = ($version >= $realVersion);
94
            }
95
96
            if (false === $termAndConditionStatus) {
97
                $request->getSession()->set('term_and_condition', ['user_id' => $user->getId()]);
98
            } else {
99
                $request->getSession()->remove('term_and_condition');
100
            }
101
102
            $termsAndCondition = $request->getSession()->get('term_and_condition');
103
            if (null !== $termsAndCondition) {
104
                $redirect = true;
105
                $allow = 'true' === Container::getSettingsManager()
106
                    ->getSetting('course.allow_public_course_with_no_terms_conditions')
107
                ;
108
109
                if (true === $allow
110
                    && Course::OPEN_WORLD === $course->getVisibility()
111
                ) {
112
                    $redirect = false;
113
                }
114
                if ($redirect && !$this->isGranted('ROLE_ADMIN')) {
115
                    $url = '/main/auth/inscription.php';
116
                    $responseData = [
117
                        'redirect' => true,
118
                        'url' => $url,
119
                    ];
120
                }
121
            }
122
        }
123
124
        return new JsonResponse($responseData);
125
    }
126
127
    #[Route('/{cid}/home.json', name: 'chamilo_core_course_home_json')]
128
    #[Entity('course', expr: 'repository.find(cid)')]
129
    public function indexJson(
130
        Request $request,
131
        CToolRepository $toolRepository,
132
        CShortcutRepository $shortcutRepository,
133
        ToolChain $toolChain,
134
        EntityManagerInterface $em
135
    ): Response {
136
        $requestData = json_decode($request->getContent(), true);
137
        // Sort behaviour
138
        if (!empty($requestData) && isset($requestData['toolItem'])) {
139
            $index = $requestData['index'];
140
            $toolItem = $requestData['toolItem'];
141
            $toolId = (int) $toolItem['ctool']['iid'];
142
143
            /** @var CTool $cTool */
144
            $cTool = $em->find(CTool::class, $toolId);
145
146
            if ($cTool) {
147
                $cTool->setPosition($index + 1);
148
                $em->persist($cTool);
149
                $em->flush();
150
            }
151
        }
152
153
        $course = $this->getCourse();
154
        $sessionId = $this->getSessionId();
155
156
        if (null === $course) {
157
            throw $this->createAccessDeniedException();
158
        }
159
160
        if (empty($sessionId)) {
161
            $this->denyAccessUnlessGranted(CourseVoter::VIEW, $course);
162
        }
163
164
        $sessionHandler = $request->getSession();
165
166
        $userId = 0;
167
168
        /** @var ?User $user */
169
        $user = $this->getUser();
170
        if (null !== $user) {
171
            $userId = $user->getId();
172
        }
173
174
        $courseCode = $course->getCode();
175
176
        if ($user && $user->hasRole('ROLE_INVITEE')) {
177
            $isInASession = $sessionId > 0;
178
            $isSubscribed = CourseManager::is_user_subscribed_in_course(
179
                $userId,
180
                $courseCode,
181
                $isInASession,
182
                $sessionId
183
            );
184
185
            if (!$isSubscribed) {
186
                throw $this->createAccessDeniedException();
187
            }
188
        }
189
190
        $isSpecialCourse = CourseManager::isSpecialCourse($course->getId());
191
192
        if ($user && $isSpecialCourse && (isset($_GET['autoreg']) && 1 === (int) $_GET['autoreg'])
193
            && CourseManager::subscribeUser($userId, $course->getId(), STUDENT)
194
        ) {
195
            $sessionHandler->set('is_allowed_in_course', true);
196
        }
197
198
        $logInfo = [
199
            'tool' => 'course-main',
200
        ];
201
        Event::registerLog($logInfo);
202
203
        $qb = $toolRepository->getResourcesByCourse($course, $this->getSession());
204
205
        $qb->addSelect('tool');
206
        $qb->innerJoin('resource.tool', 'tool');
207
        $skipTools = ['course_tool', 'chat', 'notebook', 'wiki', 'course_homepage'];
208
        $qb->andWhere($qb->expr()->notIn('resource.name', $skipTools));
209
        $qb->addOrderBy('resource.position', 'ASC');
210
211
        $result = $qb->getQuery()->getResult();
212
        $tools = [];
213
        $isCourseTeacher = $this->isGranted('ROLE_CURRENT_COURSE_TEACHER');
214
215
        /** @var CTool $item */
216
        foreach ($result as $item) {
217
            $toolModel = $toolChain->getToolFromName($item->getTool()->getName());
218
219
            if (!$isCourseTeacher && 'admin' === $toolModel->getCategory()) {
220
                continue;
221
            }
222
223
            $tools[] = [
224
                'ctool' => $item,
225
                'tool' => $toolModel,
226
                'url' => $this->generateToolUrl($toolModel),
227
                'category' => $toolModel->getCategory(),
228
            ];
229
        }
230
231
        // Deleting the objects
232
        $sessionHandler->remove('toolgroup');
233
        $sessionHandler->remove('_gid');
234
        $sessionHandler->remove('oLP');
235
        $sessionHandler->remove('lpobject');
236
237
        api_remove_in_gradebook();
238
        Exercise::cleanSessionVariables();
239
240
        $shortcuts = [];
241
        if (null !== $user) {
242
            $shortcutQuery = $shortcutRepository->getResources($course->getResourceNode());
243
            $shortcuts = $shortcutQuery->getQuery()->getResult();
244
        }
245
        $responseData = [
246
            'shortcuts' => $shortcuts,
247
            'diagram' => '',
248
            'tools' => $tools,
249
        ];
250
251
        $json = $this->serializer->serialize(
252
            $responseData,
253
            'json',
254
            [
255
                'groups' => ['course:read', 'ctool:read', 'tool:read', 'cshortcut:read'],
256
            ]
257
        );
258
259
        return new Response(
260
            $json,
261
            Response::HTTP_OK,
262
            [
263
                'Content-type' => 'application/json',
264
            ]
265
        );
266
    }
267
268
    /**
269
     * Redirects the page to a tool, following the tools settings.
270
     */
271
    #[Route('/{cid}/tool/{toolName}', name: 'chamilo_core_course_redirect_tool')]
272
    public function redirectTool(string $toolName, CToolRepository $repo, ToolChain $toolChain): RedirectResponse
273
    {
274
        /** @var CTool|null $tool */
275
        $tool = $repo->findOneBy([
276
            'name' => $toolName,
277
        ]);
278
279
        if (null === $tool) {
280
            throw new NotFoundHttpException($this->trans('Tool not found'));
281
        }
282
283
        $tool = $toolChain->getToolFromName($tool->getTool()->getName());
284
        $link = $tool->getLink();
285
286
        if (null === $this->getCourse()) {
287
            throw new NotFoundHttpException($this->trans('Course not found'));
288
        }
289
290
        if (strpos($link, 'nodeId')) {
291
            $nodeId = (string) $this->getCourse()->getResourceNode()->getId();
292
            $link = str_replace(':nodeId', $nodeId, $link);
293
        }
294
295
        $url = $link.'?'.$this->getCourseUrlQuery();
296
297
        return $this->redirect($url);
298
    }
299
300
    /*public function redirectToShortCut(string $toolName, CToolRepository $repo, ToolChain $toolChain): RedirectResponse
301
    {
302
        $tool = $repo->findOneBy([
303
            'name' => $toolName,
304
        ]);
305
306
        if (null === $tool) {
307
            throw new NotFoundHttpException($this->trans('Tool not found'));
308
        }
309
310
        $tool = $toolChain->getToolFromName($tool->getTool()->getName());
311
        $link = $tool->getLink();
312
313
        if (strpos($link, 'nodeId')) {
314
            $nodeId = (string) $this->getCourse()->getResourceNode()->getId();
315
            $link = str_replace(':nodeId', $nodeId, $link);
316
        }
317
318
        $url = $link.'?'.$this->getCourseUrlQuery();
319
320
        return $this->redirect($url);
321
    }*/
322
323
    /**
324
     * Edit configuration with given namespace.
325
     */
326
    #[Route('/{cid}/settings/{namespace}', name: 'chamilo_core_course_settings')]
327
    #[Entity('course', expr: 'repository.find(cid)')]
328
    public function updateSettings(
329
        Request $request,
330
        Course $course,
331
        string $namespace,
332
        SettingsCourseManager $manager,
333
        SettingsFormFactory $formFactory
334
    ): Response {
335
        $this->denyAccessUnlessGranted(CourseVoter::VIEW, $course);
336
337
        $schemaAlias = $manager->convertNameSpaceToService($namespace);
338
        $settings = $manager->load($namespace);
339
340
        $form = $formFactory->create($schemaAlias);
341
342
        $form->setData($settings);
343
        $form->handleRequest($request);
344
345
        if ($form->isSubmitted() && $form->isValid()) {
346
            $messageType = 'success';
347
348
            try {
349
                $manager->setCourse($course);
350
                $manager->save($form->getData());
351
                $message = $this->trans('Update');
352
            } catch (ValidatorException $validatorException) {
353
                $message = $this->trans($validatorException->getMessage());
354
                $messageType = 'error';
355
            }
356
            $this->addFlash($messageType, $message);
357
358
            if ($request->headers->has('referer')) {
359
                return $this->redirect($request->headers->get('referer'));
360
            }
361
        }
362
363
        $schemas = $manager->getSchemas();
364
365
        return $this->render(
366
            '@ChamiloCore/Course/settings.html.twig',
367
            [
368
                'course' => $course,
369
                'schemas' => $schemas,
370
                'settings' => $settings,
371
                'form' => $form->createView(),
372
            ]
373
        );
374
    }
375
376
    #[Route('/{id}/about', name: 'chamilo_core_course_about')]
377
    public function about(
378
        Course $course,
379
        IllustrationRepository $illustrationRepository,
380
        CCourseDescriptionRepository $courseDescriptionRepository,
381
        EntityManagerInterface $em
382
    ): Response {
383
        $courseId = $course->getId();
384
385
        /** @var ?User $user */
386
        $user = $this->getUser();
387
388
        $fieldsRepo = $em->getRepository(ExtraField::class);
389
390
        /** @var TagRepository $tagRepo */
391
        $tagRepo = $em->getRepository(Tag::class);
392
393
        $courseDescriptions = $courseDescriptionRepository->getResourcesByCourse($course)->getQuery()->getResult();
394
395
        $courseValues = new ExtraFieldValue('course');
396
397
        $urlCourse = api_get_path(WEB_PATH).sprintf('course/%s/about', $courseId);
398
        $courseTeachers = $course->getTeachersSubscriptions();
399
        $teachersData = [];
400
401
        foreach ($courseTeachers as $teacherSubscription) {
402
            $teacher = $teacherSubscription->getUser();
403
            $userData = [
404
                'complete_name' => UserManager::formatUserFullName($teacher),
405
                'image' => $illustrationRepository->getIllustrationUrl($teacher),
406
                'diploma' => $teacher->getDiplomas(),
407
                'openarea' => $teacher->getOpenarea(),
408
            ];
409
410
            $teachersData[] = $userData;
411
        }
412
413
        /** @var ExtraField $tagField */
414
        $tagField = $fieldsRepo->findOneBy([
415
            'itemType' => ExtraField::COURSE_FIELD_TYPE,
416
            'variable' => 'tags',
417
        ]);
418
419
        $courseTags = [];
420
        if (null !== $tagField) {
421
            $courseTags = $tagRepo->getTagsByItem($tagField, $courseId);
422
        }
423
424
        $courseDescription = $courseObjectives = $courseTopics = $courseMethodology = '';
425
        $courseMaterial = $courseResources = $courseAssessment = '';
426
        $courseCustom = [];
427
        foreach ($courseDescriptions as $descriptionTool) {
428
            switch ($descriptionTool->getDescriptionType()) {
429
                case CCourseDescription::TYPE_DESCRIPTION:
430
                    $courseDescription = $descriptionTool->getContent();
431
432
                    break;
433
434
                case CCourseDescription::TYPE_OBJECTIVES:
435
                    $courseObjectives = $descriptionTool;
436
437
                    break;
438
439
                case CCourseDescription::TYPE_TOPICS:
440
                    $courseTopics = $descriptionTool;
441
442
                    break;
443
444
                case CCourseDescription::TYPE_METHODOLOGY:
445
                    $courseMethodology = $descriptionTool;
446
447
                    break;
448
449
                case CCourseDescription::TYPE_COURSE_MATERIAL:
450
                    $courseMaterial = $descriptionTool;
451
452
                    break;
453
454
                case CCourseDescription::TYPE_RESOURCES:
455
                    $courseResources = $descriptionTool;
456
457
                    break;
458
459
                case CCourseDescription::TYPE_ASSESSMENT:
460
                    $courseAssessment = $descriptionTool;
461
462
                    break;
463
464
                case CCourseDescription::TYPE_CUSTOM:
465
                    $courseCustom[] = $descriptionTool;
466
467
                    break;
468
            }
469
        }
470
471
        $topics = [
472
            'objectives' => $courseObjectives,
473
            'topics' => $courseTopics,
474
            'methodology' => $courseMethodology,
475
            'material' => $courseMaterial,
476
            'resources' => $courseResources,
477
            'assessment' => $courseAssessment,
478
            'custom' => array_reverse($courseCustom),
479
        ];
480
481
        $subscriptionUser = false;
482
483
        if ($user) {
484
            $subscriptionUser = CourseManager::is_user_subscribed_in_course($user->getId(), $course->getCode());
485
        }
486
487
        /*$allowSubscribe = false;
488
        if ($course->getSubscribe() || api_is_platform_admin()) {
489
            $allowSubscribe = true;
490
        }
491
        $plugin = \BuyCoursesPlugin::create();
492
        $checker = $plugin->isEnabled();
493
        $courseIsPremium = null;
494
        if ($checker) {
495
            $courseIsPremium = $plugin->getItemByProduct(
496
                $courseId,
497
                \BuyCoursesPlugin::PRODUCT_TYPE_COURSE
498
            );
499
        }*/
500
501
        $image = Container::getIllustrationRepository()->getIllustrationUrl($course, 'course_picture_medium');
502
503
        $params = [
504
            'course' => $course,
505
            'description' => $courseDescription,
506
            'image' => $image,
507
            'syllabus' => $topics,
508
            'tags' => $courseTags,
509
            'teachers' => $teachersData,
510
            'extra_fields' => $courseValues->getAllValuesForAnItem(
511
                $course->getId(),
512
                null,
513
                true
514
            ),
515
            'subscription' => $subscriptionUser,
516
            'url' => '',
517
            'is_premium' => '',
518
            'token' => '',
519
        ];
520
521
        $metaInfo = '<meta property="og:url" content="'.$urlCourse.'" />';
522
        $metaInfo .= '<meta property="og:type" content="website" />';
523
        $metaInfo .= '<meta property="og:title" content="'.$course->getTitle().'" />';
524
        $metaInfo .= '<meta property="og:description" content="'.strip_tags($courseDescription).'" />';
525
        $metaInfo .= '<meta property="og:image" content="'.$image.'" />';
526
527
        $htmlHeadXtra[] = $metaInfo;
528
        $htmlHeadXtra[] = api_get_asset('readmore-js/readmore.js');
529
530
        return $this->render('@ChamiloCore/Course/about.html.twig', $params);
531
    }
532
533
    #[Route('/{id}/welcome', name: 'chamilo_core_course_welcome')]
534
    public function welcome(Course $course): Response
535
    {
536
        return $this->render('@ChamiloCore/Course/welcome.html.twig', [
537
            'course' => $course,
538
        ]);
539
    }
540
541
    private function findIntroOfCourse(Course $course)
542
    {
543
        $qb = $this->em->createQueryBuilder();
544
545
        $query = $qb->select('ct')
546
            ->from(CTool::class, 'ct')
547
            ->where('ct.course = :c_id')
548
            ->andWhere('ct.name = :name')
549
            ->andWhere(
550
                $qb->expr()->orX(
551
                    $qb->expr()->eq('ct.session', ':session_id'),
552
                    $qb->expr()->isNull('ct.session')
553
                )
554
            )
555
            ->setParameters([
556
                'c_id' => $course->getId(),
557
                'name' => 'course_homepage',
558
                'session_id' => 0,
559
            ])
560
            ->getQuery()
561
        ;
562
563
        return $query->getOneOrNullResult();
564
    }
565
566
    #[Route('/{id}/getToolIntro', name: 'chamilo_core_course_gettoolintro')]
567
    public function getToolIntro(Request $request, Course $course, EntityManagerInterface $em): Response
568
    {
569
        $sessionId = (int) $request->get('sid');
570
571
        // $session = $this->getSession();
572
        $responseData = [];
573
        $ctoolRepo = $em->getRepository(CTool::class);
574
        $sessionRepo = $em->getRepository(Session::class);
575
        $createInSession = false;
576
577
        $session = null;
578
579
        if (!empty($sessionId)) {
580
            $session = $sessionRepo->find($sessionId);
581
        }
582
583
        $ctool = $this->findIntroOfCourse($course);
584
585
        if ($session) {
586
            $ctoolSession = $ctoolRepo->findOneBy(['name' => 'course_homepage', 'course' => $course, 'session' => $session]);
587
588
            if (!$ctoolSession) {
589
                $createInSession = true;
590
            } else {
591
                $ctool = $ctoolSession;
592
            }
593
        }
594
595
        if ($ctool) {
596
            $ctoolintroRepo = $em->getRepository(CToolIntro::class);
597
598
            /** @var CToolIntro $ctoolintro */
599
            $ctoolintro = $ctoolintroRepo->findOneBy(['courseTool' => $ctool]);
600
            if ($ctoolintro) {
601
                $responseData = [
602
                    'iid' => $ctoolintro->getIid(),
603
                    'introText' => $ctoolintro->getIntroText(),
604
                    'createInSession' => $createInSession,
605
                ];
606
            }
607
            $responseData['c_tool'] = [
608
                'iid' => $ctool->getIid(),
609
                'name' => $ctool->getName(),
610
            ];
611
        }
612
613
        return new JsonResponse($responseData);
614
    }
615
616
    #[Route('/{id}/addToolIntro', name: 'chamilo_core_course_addtoolintro')]
617
    public function addToolIntro(Request $request, Course $course, EntityManagerInterface $em): Response
618
    {
619
        $data = $request->getContent();
620
        $data = json_decode($data);
621
        $ctoolintroId = $data->iid;
622
        $sessionId = $data->sid ?? 0;
623
624
        $sessionRepo = $em->getRepository(Session::class);
625
        $session = null;
626
        if (!empty($sessionId)) {
627
            $session = $sessionRepo->find($sessionId);
628
        }
629
630
        $ctool = $em->getRepository(CTool::class);
631
        $check = $ctool->findOneBy(['name' => 'course_homepage', 'course' => $course, 'session' => $session]);
632
        if (!$check) {
633
            $toolRepo = $em->getRepository(Tool::class);
634
            $toolEntity = $toolRepo->findOneBy(['name' => 'course_homepage']);
635
            $courseTool = (new CTool())
636
                ->setTool($toolEntity)
637
                ->setName('course_homepage')
638
                ->setCourse($course)
639
                ->setPosition(1)
640
                ->setVisibility(true)
641
                ->setParent($course)
642
                ->setCreator($course->getCreator())
643
                ->setSession($session)
644
                ->addCourseLink($course)
645
            ;
646
            $em->persist($courseTool);
647
            $em->flush();
648
            if ($courseTool && !empty($ctoolintroId)) {
649
                $ctoolintroRepo = Container::getToolIntroRepository();
650
651
                /** @var CToolIntro $ctoolintro */
652
                $ctoolintro = $ctoolintroRepo->find($ctoolintroId);
653
                $ctoolintro->setCourseTool($courseTool);
654
                $ctoolintroRepo->update($ctoolintro);
655
            }
656
        }
657
        $responseData = [];
658
        $json = $this->serializer->serialize(
659
            $responseData,
660
            'json',
661
            [
662
                'groups' => ['course:read', 'ctool:read', 'tool:read', 'cshortcut:read'],
663
            ]
664
        );
665
666
        return new JsonResponse($responseData);
667
    }
668
669
    #[Route('/check-enrollments', name: 'chamilo_core_check_enrollments', methods: ['GET'])]
670
    public function checkEnrollments(EntityManagerInterface $em, SettingsManager $settingsManager): JsonResponse
671
    {
672
        /** @var User|null $user */
673
        $user = $this->getUser();
674
675
        if (!$user) {
676
            return new JsonResponse(['error' => 'User not found'], Response::HTTP_UNAUTHORIZED);
677
        }
678
679
        $isEnrolledInCourses = $this->isUserEnrolledInAnyCourse($user, $em);
680
        $isEnrolledInSessions = $this->isUserEnrolledInAnySession($user, $em);
681
682
        if (!$isEnrolledInCourses && !$isEnrolledInSessions) {
683
            $defaultMenuEntry = $settingsManager->getSetting('platform.default_menu_entry_for_course_or_session');
684
            $isEnrolledInCourses = 'my_courses' === $defaultMenuEntry;
685
            $isEnrolledInSessions = 'my_sessions' === $defaultMenuEntry;
686
        }
687
688
        return new JsonResponse([
689
            'isEnrolledInCourses' => $isEnrolledInCourses,
690
            'isEnrolledInSessions' => $isEnrolledInSessions,
691
        ]);
692
    }
693
694
    private function autoLaunch(): void
695
    {
696
        $autoLaunchWarning = '';
697
        $showAutoLaunchLpWarning = false;
698
        $course_id = api_get_course_int_id();
699
        $lpAutoLaunch = api_get_course_setting('enable_lp_auto_launch');
700
        $session_id = api_get_session_id();
701
        $allowAutoLaunchForCourseAdmins =
702
            api_is_platform_admin()
703
            || api_is_allowed_to_edit(true, true)
704
            || api_is_coach();
705
706
        if (!empty($lpAutoLaunch)) {
707
            if (2 === $lpAutoLaunch) {
708
                // LP list
709
                if ($allowAutoLaunchForCourseAdmins) {
710
                    $showAutoLaunchLpWarning = true;
711
                } else {
712
                    $session_key = 'lp_autolaunch_'.$session_id.'_'.$course_id.'_'.api_get_user_id();
713
                    if (!isset($_SESSION[$session_key])) {
714
                        // Redirecting to the LP
715
                        $url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.api_get_cidreq();
716
                        $_SESSION[$session_key] = true;
717
                        header(sprintf('Location: %s', $url));
718
719
                        exit;
720
                    }
721
                }
722
            } else {
723
                $lp_table = Database::get_course_table(TABLE_LP_MAIN);
724
                $condition = '';
725
                if (!empty($session_id)) {
726
                    $condition = api_get_session_condition($session_id);
727
                    $sql = "SELECT id FROM {$lp_table}
728
                            WHERE c_id = {$course_id} AND autolaunch = 1 {$condition}
729
                            LIMIT 1";
730
                    $result = Database::query($sql);
731
                    // If we found nothing in the session we just called the session_id =  0 autolaunch
732
                    if (0 === Database::num_rows($result)) {
733
                        $condition = '';
734
                    }
735
                }
736
737
                $sql = "SELECT iid FROM {$lp_table}
738
                        WHERE c_id = {$course_id} AND autolaunch = 1 {$condition}
739
                        LIMIT 1";
740
                $result = Database::query($sql);
741
                if (Database::num_rows($result) > 0) {
742
                    $lp_data = Database::fetch_array($result);
743
                    if (!empty($lp_data['iid'])) {
744
                        if ($allowAutoLaunchForCourseAdmins) {
745
                            $showAutoLaunchLpWarning = true;
746
                        } else {
747
                            $session_key = 'lp_autolaunch_'.$session_id.'_'.api_get_course_int_id().'_'.api_get_user_id();
748
                            if (!isset($_SESSION[$session_key])) {
749
                                // Redirecting to the LP
750
                                $url = api_get_path(WEB_CODE_PATH).
751
                                    'lp/lp_controller.php?'.api_get_cidreq().'&action=view&lp_id='.$lp_data['iid'];
752
753
                                $_SESSION[$session_key] = true;
754
                                header(sprintf('Location: %s', $url));
755
756
                                exit;
757
                            }
758
                        }
759
                    }
760
                }
761
            }
762
        }
763
764
        if ($showAutoLaunchLpWarning) {
765
            $autoLaunchWarning = get_lang(
766
                'The learning path auto-launch setting is ON. When learners enter this course, they will be automatically redirected to the learning path marked as auto-launch.'
767
            );
768
        }
769
770
        $forumAutoLaunch = (int) api_get_course_setting('enable_forum_auto_launch');
771
        if (1 === $forumAutoLaunch) {
772
            if ($allowAutoLaunchForCourseAdmins) {
773
                if (empty($autoLaunchWarning)) {
774
                    $autoLaunchWarning = get_lang(
775
                        "The forum's auto-launch setting is on. Students will be redirected to the forum tool when entering this course."
776
                    );
777
                }
778
            } else {
779
                $url = api_get_path(WEB_CODE_PATH).'forum/index.php?'.api_get_cidreq();
780
                header(sprintf('Location: %s', $url));
781
782
                exit;
783
            }
784
        }
785
786
        if ('true' === api_get_setting('exercise.allow_exercise_auto_launch')) {
787
            $exerciseAutoLaunch = (int) api_get_course_setting('enable_exercise_auto_launch');
788
            if (2 === $exerciseAutoLaunch) {
789
                if ($allowAutoLaunchForCourseAdmins) {
790
                    if (empty($autoLaunchWarning)) {
791
                        $autoLaunchWarning = get_lang(
792
                            'TheExerciseAutoLaunchSettingIsONStudentsWillBeRedirectToTheExerciseList'
793
                        );
794
                    }
795
                } else {
796
                    // Redirecting to the document
797
                    $url = api_get_path(WEB_CODE_PATH).'exercise/exercise.php?'.api_get_cidreq();
798
                    header(sprintf('Location: %s', $url));
799
800
                    exit;
801
                }
802
            } elseif (1 === $exerciseAutoLaunch) {
803
                if ($allowAutoLaunchForCourseAdmins) {
804
                    if (empty($autoLaunchWarning)) {
805
                        $autoLaunchWarning = get_lang(
806
                            'TheExerciseAutoLaunchSettingIsONStudentsWillBeRedirectToAnSpecificExercise'
807
                        );
808
                    }
809
                } else {
810
                    // Redirecting to an exercise
811
                    $table = Database::get_course_table(TABLE_QUIZ_TEST);
812
                    $condition = '';
813
                    if (!empty($session_id)) {
814
                        $condition = api_get_session_condition($session_id);
815
                        $sql = "SELECT iid FROM {$table}
816
                                WHERE c_id = {$course_id} AND autolaunch = 1 {$condition}
817
                                LIMIT 1";
818
                        $result = Database::query($sql);
819
                        // If we found nothing in the session we just called the session_id = 0 autolaunch
820
                        if (0 === Database::num_rows($result)) {
821
                            $condition = '';
822
                        }
823
                    }
824
825
                    $sql = "SELECT iid FROM {$table}
826
                            WHERE c_id = {$course_id} AND autolaunch = 1 {$condition}
827
                            LIMIT 1";
828
                    $result = Database::query($sql);
829
                    if (Database::num_rows($result) > 0) {
830
                        $row = Database::fetch_array($result);
831
                        $exerciseId = $row['iid'];
832
                        $url = api_get_path(WEB_CODE_PATH).
833
                            'exercise/overview.php?exerciseId='.$exerciseId.'&'.api_get_cidreq();
834
                        header(sprintf('Location: %s', $url));
835
836
                        exit;
837
                    }
838
                }
839
            }
840
        }
841
842
        $documentAutoLaunch = (int) api_get_course_setting('enable_document_auto_launch');
843
        if (1 === $documentAutoLaunch) {
844
            if ($allowAutoLaunchForCourseAdmins) {
845
                if (empty($autoLaunchWarning)) {
846
                    $autoLaunchWarning = get_lang(
847
                        'The document auto-launch feature configuration is enabled. Learners will be automatically redirected to document tool.'
848
                    );
849
                }
850
            } else {
851
                // Redirecting to the document
852
                $url = api_get_path(WEB_CODE_PATH).'document/document.php?'.api_get_cidreq();
853
                header("Location: $url");
854
855
                exit;
856
            }
857
        }
858
859
        /*  SWITCH TO A DIFFERENT HOMEPAGE VIEW
860
         the setting homepage_view is adjustable through
861
         the platform administration section */
862
        if (!empty($autoLaunchWarning)) {
863
            $this->addFlash(
864
                'warning',
865
                Display::return_message(
866
                    $autoLaunchWarning,
867
                    'warning'
868
                )
869
            );
870
        }
871
    }
872
873
    private function generateToolUrl(AbstractTool $tool): string
874
    {
875
        $link = $tool->getLink();
876
        $course = $this->getCourse();
877
878
        if (strpos($link, 'nodeId')) {
879
            $nodeId = (string) $course->getResourceNode()->getId();
880
            $link = str_replace(':nodeId', $nodeId, $link);
881
        }
882
883
        return $link.'?'.$this->getCourseUrlQuery();
884
    }
885
886
    // Implement the real logic to check course enrollment
887
    private function isUserEnrolledInAnyCourse(User $user, EntityManagerInterface $em): bool
888
    {
889
        $enrollmentCount = $em
890
            ->getRepository(CourseRelUser::class)
891
            ->count(['user' => $user])
892
        ;
893
894
        return $enrollmentCount > 0;
895
    }
896
897
    // Implement the real logic to check session enrollment
898
    private function isUserEnrolledInAnySession(User $user, EntityManagerInterface $em): bool
899
    {
900
        $enrollmentCount = $em->getRepository(SessionRelUser::class)
901
            ->count(['user' => $user])
902
        ;
903
904
        return $enrollmentCount > 0;
905
    }
906
}
907