Merge pull request #5859 from christianbeeznest/storm-22103

Course: Implement document auto-launch and notification for students in course home - refs BT#22103
pull/5943/head
Nicolas Ducoulombier 10 months ago committed by GitHub
commit ef94109a01
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 117
      assets/vue/router/index.js
  2. 67
      assets/vue/services/courseService.js
  3. 28
      assets/vue/views/course/CourseHome.vue
  4. 228
      public/main/course_info/infocours.php
  5. 20
      public/main/exercise/exercise.class.php
  6. 45
      public/main/lp/learnpath.class.php
  7. 2
      public/main/lp/lp_list.php
  8. 46
      src/CoreBundle/Controller/CourseController.php
  9. 5
      src/CoreBundle/Controller/PlatformConfigurationController.php
  10. 13
      src/CourseBundle/Repository/CLpRepository.php
  11. 16
      src/CourseBundle/Repository/CQuizRepository.php

@ -1,4 +1,4 @@
import { createRouter, createWebHistory } from "vue-router"
import {createRouter, createWebHistory} from "vue-router"
import adminRoutes from "./admin"
import courseRoutes from "./course"
import accountRoutes from "./account"
@ -37,13 +37,15 @@ import Login from "../pages/Login.vue"
import Faq from "../pages/Faq.vue"
import Demo from "../pages/Demo.vue"
import { useCidReqStore } from "../store/cidReq"
import {useCidReqStore} from "../store/cidReq"
import courseService from "../services/courseService"
import catalogueCourses from "./cataloguecourses"
import catalogueSessions from "./cataloguesessions"
import { customVueTemplateEnabled } from "../config/env"
import { useUserSessionSubscription } from "../composables/userPermissions"
import {customVueTemplateEnabled} from "../config/env"
import {useCourseSettings} from "../store/courseSettingStore"
import {checkIsAllowedToEdit} from "../composables/userPermissions"
import {usePlatformConfig} from "../store/platformConfig"
const router = createRouter({
history: createWebHistory(),
@ -97,17 +99,97 @@ const router = createRouter({
name: "CourseHome",
component: CourseHome,
beforeEnter: async (to) => {
try {
const check = await courseService.checkLegal(to.params.id, to.query?.sid)
const courseId = to.params.id
const sessionId = to.query?.sid
const autoLaunchKey = `course_autolaunch_${courseId}`
const hasAutoLaunched = sessionStorage.getItem(autoLaunchKey)
if (hasAutoLaunched === "true") {
return true
}
try {
const check = await courseService.checkLegal(courseId, sessionId)
if (check.redirect) {
window.location.href = check.url
return false
}
} catch (e) {
return true
const course = await courseService.getCourseDetails(courseId)
if (!course) {
return false
}
const isAllowedToEdit = await checkIsAllowedToEdit(true, true, true)
if (isAllowedToEdit) {
return true
}
const courseSettingsStore = useCourseSettings()
await courseSettingsStore.loadCourseSettings(courseId, sessionId)
// Document auto-launch
const documentAutoLaunch = parseInt(courseSettingsStore.getSetting("enable_document_auto_launch"), 10) || 0
if (documentAutoLaunch === 1 && course.resourceNode?.id) {
sessionStorage.setItem(autoLaunchKey, "true")
window.location.href = `/resources/document/${course.resourceNode.id}/?cid=${courseId}`
+ (sessionId ? `&sid=${sessionId}` : '')
return false
}
// Exercise auto-launch
const platformConfigStore = usePlatformConfig()
const isExerciseAutoLaunchEnabled = "true" === platformConfigStore.getSetting("exercise.allow_exercise_auto_launch")
if (isExerciseAutoLaunchEnabled) {
const exerciseAutoLaunch = parseInt(courseSettingsStore.getSetting("enable_exercise_auto_launch"), 10) || 0
if (exerciseAutoLaunch === 2) {
sessionStorage.setItem(autoLaunchKey, "true")
window.location.href = `/main/exercise/exercise.php?cid=${courseId}`
+ (sessionId ? `&sid=${sessionId}` : '')
return false
} else if (exerciseAutoLaunch === 1) {
const exerciseId = await courseService.getAutoLaunchExerciseId(courseId, sessionId)
if (exerciseId) {
sessionStorage.setItem(autoLaunchKey, "true")
window.location.href = `/main/exercise/overview.php?exerciseId=${exerciseId}&cid=${courseId}`
+ (sessionId ? `&sid=${sessionId}` : '')
return false
}
}
}
// Learning path auto-launch
const lpAutoLaunch = parseInt(courseSettingsStore.getSetting("enable_lp_auto_launch"), 10) || 0
if (lpAutoLaunch === 2) {
sessionStorage.setItem(autoLaunchKey, "true")
window.location.href = `/main/lp/lp_controller.php?cid=${courseId}`
+ (sessionId ? `&sid=${sessionId}` : '')
return false
} else if (lpAutoLaunch === 1) {
const lpId = await courseService.getAutoLaunchLPId(courseId, sessionId)
if (lpId) {
sessionStorage.setItem(autoLaunchKey, "true")
window.location.href = `/main/lp/lp_controller.php?lp_id=${lpId}&cid=${courseId}&action=view&isStudentView=true`
+ (sessionId ? `&sid=${sessionId}` : '')
return false
}
}
// Forum auto-launch
const forumAutoLaunch = parseInt(courseSettingsStore.getSetting("enable_forum_auto_launch"), 10) || 0
if (forumAutoLaunch === 1) {
sessionStorage.setItem(autoLaunchKey, "true")
window.location.href = `/main/forum/index.php?cid=${courseId}`
+ (sessionId ? `&sid=${sessionId}` : '')
return false
}
} catch (error) {
console.error("Error during CourseHome route guard:", error)
}
return true
},
},
{
@ -175,6 +257,24 @@ const router = createRouter({
router.beforeEach(async (to, from, next) => {
const securityStore = useSecurityStore()
if (!securityStore.isAuthenticated) {
sessionStorage.clear()
}
let cid = parseInt(to.query?.cid ?? 0)
if ("CourseHome" === to.name) {
cid = parseInt(to.params?.id ?? 0)
}
if (!cid) {
for (const key in sessionStorage) {
if (key.startsWith('course_autolaunch_')) {
sessionStorage.removeItem(key)
}
}
}
if (to.matched.some((record) => record.meta.requiresAuth)) {
if (!securityStore.isLoading) {
await securityStore.checkSession()
@ -183,6 +283,7 @@ router.beforeEach(async (to, from, next) => {
if (securityStore.isAuthenticated) {
next()
} else {
sessionStorage.clear()
next({
path: "/login",
query: { redirect: to.fullPath },

@ -106,4 +106,71 @@ export default {
value: item.id,
}))
},
/**
* Fetches course details by course ID.
*
* @param {number} courseId - The ID of the course.
* @returns {Promise<Object|null>} - The course details or null if an error occurs.
*/
getCourseDetails: async (courseId) => {
try {
const response = await api.get(`/api/courses/${courseId}`)
return response.data
} catch (error) {
console.error("Error fetching course details:", error)
return null
}
},
/**
* Retrieves the ID of the auto-launchable exercise in a course, if configured.
*
* @param {number} courseId - The ID of the course.
* @param {number=} sessionId - The ID of the session (optional).
* @returns {Promise<number|null>} The ID of the auto-launchable exercise, or null if none exists.
*/
getAutoLaunchExerciseId: async (courseId, sessionId = 0) => {
try {
const { data } = await api.get(`/course/${courseId}/getAutoLaunchExerciseId`, {
params: {
sid: sessionId,
},
});
if (data && data.exerciseId) {
return data.exerciseId;
}
return null;
} catch (error) {
console.error("Error fetching auto-launch exercise ID:", error);
return null;
}
},
/**
* Retrieves the ID of the auto-launchable learnpaths in a course, if configured.
*
* @param {number} courseId - The ID of the course.
* @param {number=} sessionId - The ID of the session (optional).
* @returns {Promise<number|null>} The ID of the auto-launchable learnpath, or null if none exists.
*/
getAutoLaunchLPId: async (courseId, sessionId = 0) => {
try {
const { data } = await api.get(`/course/${courseId}/getAutoLaunchLPId`, {
params: {
sid: sessionId,
},
});
if (data && data.lpId) {
return data.lpId;
}
return null;
} catch (error) {
console.error("Error fetching auto-launch LP ID:", error);
return null;
}
},
}

@ -81,6 +81,22 @@
<small v-if="session"> ({{ session.title }}) </small>
</h2>
<p v-if="isAllowedToEdit && documentAutoLaunch === 1" class="text-sm text-gray-600">
{{ t('Document auto-launch is enabled for students') }}
</p>
<p v-if="isAllowedToEdit && (exerciseAutoLaunch === 1 || exerciseAutoLaunch === 2)" class="text-sm text-gray-600">
{{ t('Exercise auto-launch is enabled for students') }}
</p>
<p v-if="isAllowedToEdit && (lpAutoLaunch === 1 || lpAutoLaunch === 2)" class="text-sm text-gray-600">
{{ t('LP auto-launch is enabled for students') }}
</p>
<p v-if="isAllowedToEdit && (forumAutoLaunch === 1 || forumAutoLaunch === 2)" class="text-sm text-gray-600">
{{ t('Forum auto-launch is enabled for students') }}
</p>
<div class="grow-0">
<StudentViewButton
v-if="course"
@ -220,6 +236,7 @@ import courseService from "../../services/courseService"
import CourseIntroduction from "../../components/course/CourseIntroduction.vue"
import { usePlatformConfig } from "../../store/platformConfig"
import { useSecurityStore } from "../../store/securityStore"
import {useCourseSettings} from "../../store/courseSettingStore"
const { t } = useI18n()
const cidReqStore = useCidReqStore()
@ -244,6 +261,11 @@ provide("isCustomizing", isCustomizing)
const courseItems = ref([])
const routerTools = ["document", "link", "glossary", "agenda", "student_publication", "course_homepage"]
const documentAutoLaunch = ref(0)
const exerciseAutoLaunch = ref(0)
const lpAutoLaunch = ref(0)
const forumAutoLaunch = ref(0)
const courseSettingsStore = useCourseSettings()
courseService.loadCTools(course.value.id, session.value?.id).then((cTools) => {
tools.value = cTools.map((element) => {
@ -377,6 +399,12 @@ onMounted(async () => {
translateHtml()
}, 1000)
}
await courseSettingsStore.loadCourseSettings(course.value.id, session.value?.id)
documentAutoLaunch.value = parseInt(courseSettingsStore.getSetting("enable_document_auto_launch"), 10) || 0
exerciseAutoLaunch.value = parseInt(courseSettingsStore.getSetting("enable_exercise_auto_launch"), 10) || 0
lpAutoLaunch.value = parseInt(courseSettingsStore.getSetting("enable_lp_auto_launch"), 10) || 0
forumAutoLaunch.value = parseInt(courseSettingsStore.getSetting("enable_forum_auto_launch"), 10) || 0
})
const onStudentViewChanged = async () => {

@ -290,19 +290,6 @@ if ('true' == api_get_setting('show_default_folders')) {
$myButton = $form->addButtonSave(get_lang('Save settings'), 'submit_save', true);
}
$group = [];
$group[] = $form->createElement(
'radio',
'enable_document_auto_launch',
get_lang('Auto-launch for documents'),
get_lang('Redirect to the document list'),
1
);
$group[] = $form->createElement('radio', 'enable_document_auto_launch', null, get_lang('Deactivate'), 0);
$globalGroup[get_lang('Auto-launch for documents')] = $group;
$globalGroup[] = $myButton;
$form->addPanelOption(
'documents',
get_lang('Documents'),
@ -567,24 +554,6 @@ $form->addPanelOption(
);
$globalGroup = [];
$group = [];
$group[] = $form->createElement(
'radio',
'enable_lp_auto_launch',
get_lang('Enable learning path auto-launch'),
get_lang('Redirect to a selected learning path'),
1
);
$group[] = $form->createElement(
'radio',
'enable_lp_auto_launch',
get_lang('Enable learning path auto-launch'),
get_lang('Redirect to the learning paths list'),
2
);
$group[] = $form->createElement('radio', 'enable_lp_auto_launch', null, get_lang('Disable'), 0);
$globalGroup[get_lang('Enable learning path auto-launch')] = $group;
if ('true' === api_get_setting('allow_course_theme')) {
// Allow theme into Learning path
@ -687,49 +656,6 @@ $form->addPanelOption(
false
);
if ('true' === api_get_setting('exercise.allow_exercise_auto_launch')) {
$globalGroup = [];
// Auto launch exercise
$group = [];
$group[] = $form->createElement(
'radio',
'enable_exercise_auto_launch',
get_lang('Auto-launch for exercises'),
get_lang('Redirect to the selected exercise'),
1
);
$group[] = $form->createElement(
'radio',
'enable_exercise_auto_launch',
get_lang('Auto-launch for exercises'),
get_lang('Redirect to the exercises list'),
2
);
$group[] = $form->createElement('radio', 'enable_exercise_auto_launch', null, get_lang('Disable'), 0);
$globalGroup[get_lang("Auto-launch for exercises")] = $group;
if ($isEditable) {
$myButton = $form->addButtonSave(get_lang('Save settings'), 'submit_save', true);
$globalGroup[] = $myButton;
} else {
// Is it allowed to edit the course settings?
if (!$isEditable) {
$disabled_output = "disabled";
}
$form->freeze();
}
$form->addPanelOption(
'config_exercise',
get_lang('Test'),
$globalGroup,
ToolIcon::QUIZ,
false
);
}
// START THEMATIC
$group = [];
$group[] = $form->createElement(
@ -802,10 +728,6 @@ if ('true' === api_get_setting('allow_public_certificates')) {
}
// Forum settings
$group = [
$form->createElement('radio', 'enable_forum_auto_launch', null, get_lang('Redirect to forums list'), 1),
$form->createElement('radio', 'enable_forum_auto_launch', null, get_lang('Disabled'), 2),
];
$myButton = $form->addButtonSave(get_lang('Save settings'), 'submit_save', true);
// Forum settings
@ -820,7 +742,6 @@ $addUsers = [
];
$globalGroup = [
get_lang('Enable forum auto-launch') => $group,
get_lang('Hide forum notifications') => $groupNotification,
get_lang('Subscribe automatically all users to all forum notifications') => $addUsers,
'' => $myButton,
@ -859,6 +780,83 @@ $form->addPanelOption(
false
);
// Auto-launch settings for documents, exercises, learning paths, and forums
$globalGroup = [];
$group = [];
// Auto-launch for documents
$group[] = $form->createElement(
'radio',
'auto_launch_option',
get_lang('Auto-launch for documents'),
get_lang('Redirect to the document list'),
'enable_document_auto_launch'
);
// Auto-launch for learning paths
$group[] = $form->createElement(
'radio',
'auto_launch_option',
get_lang('Enable learning path auto-launch'),
get_lang('Redirect to a selected learning path'),
'enable_lp_auto_launch'
);
$group[] = $form->createElement(
'radio',
'auto_launch_option',
get_lang('Enable learning path auto-launch'),
get_lang('Redirect to the learning paths list'),
'enable_lp_auto_launch_list'
);
// Auto-launch for exercises
$group[] = $form->createElement(
'radio',
'auto_launch_option',
get_lang('Auto-launch for exercises'),
get_lang('Redirect to the selected exercise'),
'enable_exercise_auto_launch'
);
$group[] = $form->createElement(
'radio',
'auto_launch_option',
get_lang('Auto-launch for exercises'),
get_lang('Redirect to the exercises list'),
'enable_exercise_auto_launch_list'
);
// Auto-launch for forums
$group[] = $form->createElement(
'radio',
'auto_launch_option',
get_lang('Auto-launch for forums'),
get_lang('Redirect to forums list'),
'enable_forum_auto_launch'
);
// Option to deactivate all auto-launch options
$group[] = $form->createElement(
'radio',
'auto_launch_option',
get_lang('Disable all auto-launch options'),
get_lang('Disable'),
'disable_auto_launch'
);
$myButton = $form->addButtonSave(get_lang('Save settings'), 'submit_save', true);
$globalGroup = [
get_lang('Auto-launch') => $group,
'' => $myButton,
];
$form->addPanelOption(
'autolaunch',
get_lang('Autolaunch settings'),
$globalGroup,
ToolIcon::COURSE,
false
);
$button = Display::toolbarButton(
get_lang('Configure external tools'),
$router->generate('chamilo_lti_configure', ['cid' => $courseId]).'?'.api_get_cidreq(),
@ -869,20 +867,6 @@ $html = [
$form->createElement('html', '<p>'.get_lang('LTI intro tool').'</p>'.$button),
];
/*$form->addPanelOption(
'lti_tool',
$translator->trans('External tools'),
$html,
ToolIcon::PLUGIN,
false
);*/
// Plugin course settings
//$appPlugin = new AppPlugin();
//$appPlugin->add_course_settings_form($form);
//$form->addHtml('</div>');
// Set the default values of the form
$values = [];
$values['title'] = $_course['name'];
@ -909,6 +893,29 @@ foreach ($courseSettings as $setting) {
if (!isset($values['student_delete_own_publication'])) {
$values['student_delete_own_publication'] = 0;
}
$documentAutoLaunch = api_get_course_setting('enable_document_auto_launch');
$lpAutoLaunch = api_get_course_setting('enable_lp_auto_launch');
$exerciseAutoLaunch = api_get_course_setting('enable_exercise_auto_launch');
$forumAutoLaunch = api_get_course_setting('enable_forum_auto_launch');
$defaultAutoLaunchOption = 'disable_auto_launch';
if ($documentAutoLaunch == 1) {
$defaultAutoLaunchOption = 'enable_document_auto_launch';
} elseif ($lpAutoLaunch == 1) {
$defaultAutoLaunchOption = 'enable_lp_auto_launch';
} elseif ($lpAutoLaunch == 2) {
$defaultAutoLaunchOption = 'enable_lp_auto_launch_list';
} elseif ($exerciseAutoLaunch == 1) {
$defaultAutoLaunchOption = 'enable_exercise_auto_launch';
} elseif ($exerciseAutoLaunch == 2) {
$defaultAutoLaunchOption = 'enable_exercise_auto_launch_list';
} elseif ($forumAutoLaunch == 1) {
$defaultAutoLaunchOption = 'enable_forum_auto_launch';
}
$values['auto_launch_option'] = $defaultAutoLaunchOption;
$form->setDefaults($values);
// Validate form
@ -990,10 +997,37 @@ if ($form->validate()) {
$activeLegal = $updateValues['activate_legal'] ?? 0;
/*$category = null;
if (!empty($updateValues['category_id'])) {
$category = $courseCategoryRepo->find($updateValues['category_id']);
}*/
$autoLaunchOption = $updateValues['auto_launch_option'] ?? 'disable_auto_launch';
$updateValues['enable_document_auto_launch'] = 0;
$updateValues['enable_lp_auto_launch'] = 0;
$updateValues['enable_lp_auto_launch_list'] = 0;
$updateValues['enable_exercise_auto_launch'] = 0;
$updateValues['enable_exercise_auto_launch_list'] = 0;
$updateValues['enable_forum_auto_launch'] = 0;
switch ($autoLaunchOption) {
case 'enable_document_auto_launch':
$updateValues['enable_document_auto_launch'] = 1;
break;
case 'enable_lp_auto_launch':
$updateValues['enable_lp_auto_launch'] = 1;
break;
case 'enable_lp_auto_launch_list':
$updateValues['enable_lp_auto_launch'] = 2;
break;
case 'enable_exercise_auto_launch':
$updateValues['enable_exercise_auto_launch'] = 1;
break;
case 'enable_exercise_auto_launch_list':
$updateValues['enable_exercise_auto_launch'] = 2;
break;
case 'enable_forum_auto_launch':
$updateValues['enable_forum_auto_launch'] = 1;
break;
case 'disable_auto_launch':
default:
break;
}
$courseEntity
->setTitle($updateValues['title'])

@ -8534,10 +8534,22 @@ class Exercise
*/
public function cleanCourseLaunchSettings()
{
$table = Database::get_course_table(TABLE_QUIZ_TEST);
$sql = "UPDATE $table SET autolaunch = 0
WHERE c_id = ".$this->course_id.' AND session_id = '.$this->sessionId;
Database::query($sql);
$em = Database::getManager();
$repo = Container::getQuizRepository();
$session = api_get_session_entity();
$course = api_get_course_entity();
$qb = $repo->getResourcesByCourse($course, $session);
$quizzes = $qb->getQuery()->getResult();
foreach ($quizzes as $quiz) {
$quiz->setAutoLaunch(false);
$em->persist($quiz);
}
$em->flush();
}
/**

@ -6960,31 +6960,30 @@ class learnpath
*/
public function set_autolaunch($lp_id, $status)
{
$course_id = api_get_course_int_id();
$lp_id = (int) $lp_id;
$status = (int) $status;
$lp_table = Database::get_course_table(TABLE_LP_MAIN);
$em = Database::getManager();
$repo = Container::getLpRepository();
// Setting everything to autolaunch = 0
$attributes['autolaunch'] = 0;
$where = [
'session_id = ? AND c_id = ? ' => [
api_get_session_id(),
$course_id,
],
];
Database::update($lp_table, $attributes, $where);
if (1 == $status) {
//Setting my lp_id to autolaunch = 1
$attributes['autolaunch'] = 1;
$where = [
'iid = ? AND session_id = ? AND c_id = ?' => [
$lp_id,
api_get_session_id(),
$course_id,
],
];
Database::update($lp_table, $attributes, $where);
$session = api_get_session_entity();
$course = api_get_course_entity();
$qb = $repo->getResourcesByCourse($course, $session);
$lps = $qb->getQuery()->getResult();
foreach ($lps as $lp) {
$lp->setAutoLaunch(0);
$em->persist($lp);
}
$em->flush();
if ($status === 1) {
$lp = $repo->find($lp_id);
if ($lp) {
$lp->setAutolaunch(1);
$em->persist($lp);
}
$em->flush();
}
}

@ -684,7 +684,7 @@ foreach ($categories as $category) {
);
} else {
$lp_auto_launch_icon = Display::url(
Display::getMdiIcon('rocket-launch', 'ch-tool-icon', '', 22),
Display::getMdiIcon('rocket-launch', 'ch-tool-icon-disabled', '', 22),
api_get_self().'?'.$cidReq."&action=auto_launch&status=1&lp_id=$id",
['title' => htmlentities(get_lang('Enable learning path auto-launch'))]
);

@ -33,6 +33,8 @@ use Chamilo\CourseBundle\Entity\CCourseDescription;
use Chamilo\CourseBundle\Entity\CTool;
use Chamilo\CourseBundle\Entity\CToolIntro;
use Chamilo\CourseBundle\Repository\CCourseDescriptionRepository;
use Chamilo\CourseBundle\Repository\CLpRepository;
use Chamilo\CourseBundle\Repository\CQuizRepository;
use Chamilo\CourseBundle\Repository\CShortcutRepository;
use Chamilo\CourseBundle\Repository\CToolRepository;
use Chamilo\CourseBundle\Settings\SettingsCourseManager;
@ -756,6 +758,50 @@ class CourseController extends ToolBaseController
return new JsonResponse(['success' => false, 'message' => $translator->trans('An error occurred while creating the course.')]);
}
#[Route('/{id}/getAutoLaunchExerciseId', name: 'chamilo_core_course_get_auto_launch_exercise_id', methods: ['GET'])]
public function getAutoLaunchExerciseId(
Request $request,
Course $course,
CQuizRepository $quizRepository,
EntityManagerInterface $em
): JsonResponse {
$data = $request->getContent();
$data = json_decode($data);
$sessionId = $data->sid ?? 0;
$sessionRepo = $em->getRepository(Session::class);
$session = null;
if (!empty($sessionId)) {
$session = $sessionRepo->find($sessionId);
}
$autoLaunchExerciseId = $quizRepository->findAutoLaunchableQuizByCourseAndSession($course, $session);
return new JsonResponse(['exerciseId' => $autoLaunchExerciseId], Response::HTTP_OK);
}
#[Route('/{id}/getAutoLaunchLPId', name: 'chamilo_core_course_get_auto_launch_lp_id', methods: ['GET'])]
public function getAutoLaunchLPId(
Request $request,
Course $course,
CLPRepository $lpRepository,
EntityManagerInterface $em
): JsonResponse {
$data = $request->getContent();
$data = json_decode($data);
$sessionId = $data->sid ?? 0;
$sessionRepo = $em->getRepository(Session::class);
$session = null;
if (!empty($sessionId)) {
$session = $sessionRepo->find($sessionId);
}
$autoLaunchLPId = $lpRepository->findAutoLaunchableLPByCourseAndSession($course, $session);
return new JsonResponse(['lpId' => $autoLaunchLPId], Response::HTTP_OK);
}
private function autoLaunch(): void
{
$autoLaunchWarning = '';

@ -91,6 +91,7 @@ class PlatformConfigurationController extends AbstractController
'document.students_download_folders',
'social.hide_social_groups_block',
'course.show_course_duration',
'exercise.allow_exercise_auto_launch',
];
$user = $this->userHelper->getCurrent();
@ -145,6 +146,10 @@ class PlatformConfigurationController extends AbstractController
$settings = [
'show_course_in_user_language' => $courseSettingsManager->getCourseSettingValue('show_course_in_user_language'),
'allow_user_edit_agenda' => $courseSettingsManager->getCourseSettingValue('allow_user_edit_agenda'),
'enable_document_auto_launch' => $courseSettingsManager->getCourseSettingValue('enable_document_auto_launch'),
'enable_exercise_auto_launch' => $courseSettingsManager->getCourseSettingValue('enable_exercise_auto_launch'),
'enable_lp_auto_launch' => $courseSettingsManager->getCourseSettingValue('enable_lp_auto_launch'),
'enable_forum_auto_launch' => $courseSettingsManager->getCourseSettingValue('enable_forum_auto_launch'),
];
return new JsonResponse(['settings' => $settings]);

@ -95,6 +95,19 @@ final class CLpRepository extends ResourceRepository implements ResourceWithLink
return $router->generate('legacy_main', $params);
}
public function findAutoLaunchableLPByCourseAndSession(Course $course, ?Session $session = null): ?int
{
$qb = $this->getResourcesByCourse($course, $session)
->select('resource.iid')
->andWhere('resource.autolaunch = 1');
$qb->setMaxResults(1);
$result = $qb->getQuery()->getOneOrNullResult();
return $result ? $result['iid'] : null;
}
protected function addNotDeletedQueryBuilder(?QueryBuilder $qb = null): QueryBuilder
{
$qb = $this->getOrCreateQueryBuilder($qb);

@ -133,4 +133,20 @@ final class CQuizRepository extends ResourceRepository implements ResourceWithLi
return $qb;
}
/**
* Finds the auto-launchable quiz for the given course and session.
*/
public function findAutoLaunchableQuizByCourseAndSession(Course $course, ?Session $session = null): ?int
{
$qb = $this->getResourcesByCourse($course, $session)
->select('resource.iid')
->andWhere('resource.autoLaunch = 1');
$qb->setMaxResults(1);
$result = $qb->getQuery()->getOneOrNullResult();
return $result ? $result['iid'] : null;
}
}

Loading…
Cancel
Save