Course: Fix and implement exercise auto-launch functionality with messaging - refs BT#22104

pull/5859/head
christianbeeznst 11 months ago
parent c15ec66a76
commit 676be3d85e
  1. 27
      assets/vue/router/index.js
  2. 28
      assets/vue/services/courseService.js
  3. 6
      assets/vue/views/course/CourseHome.vue
  4. 20
      public/main/exercise/exercise.class.php
  5. 23
      src/CoreBundle/Controller/CourseController.php
  6. 2
      src/CoreBundle/Controller/PlatformConfigurationController.php
  7. 16
      src/CourseBundle/Repository/CQuizRepository.php

@ -43,8 +43,9 @@ import courseService from "../services/courseService"
import catalogueCourses from "./cataloguecourses"
import catalogueSessions from "./cataloguesessions"
import {customVueTemplateEnabled} from "../config/env"
import {useCourseSettings} from "../store/courseSettingStore";
import {checkIsAllowedToEdit} from "../composables/userPermissions";
import {useCourseSettings} from "../store/courseSettingStore"
import {checkIsAllowedToEdit} from "../composables/userPermissions"
import {usePlatformConfig} from "../store/platformConfig"
const router = createRouter({
history: createWebHistory(),
@ -125,8 +126,26 @@ const router = createRouter({
window.location.href = `/resources/document/${course.resourceNode.id}/?cid=${courseId}`
+ (sessionId ? `&sid=${sessionId}` : '')
return false
} else {
console.log("Document auto launch is disabled or resourceNode ID is missing.")
}
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) {
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) {
window.location.href = `/main/exercise/overview.php?exerciseId=${exerciseId}&cid=${courseId}`
+ (sessionId ? `&sid=${sessionId}` : '')
return false
}
}
}
} catch (error) {

@ -127,5 +127,31 @@ export default {
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;
}
},
}

@ -85,6 +85,10 @@
{{ 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>
<div class="grow-0">
<StudentViewButton
v-if="course"
@ -251,6 +255,7 @@ const courseItems = ref([])
const routerTools = ["document", "link", "glossary", "agenda", "student_publication", "course_homepage"]
const documentAutoLaunch = ref(0)
const exerciseAutoLaunch = ref(0)
const courseSettingsStore = useCourseSettings()
courseService.loadCTools(course.value.id, session.value?.id).then((cTools) => {
@ -397,6 +402,7 @@ onMounted(async () => {
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
})
const onStudentViewChanged = async () => {

@ -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();
}
/**

@ -33,6 +33,7 @@ use Chamilo\CourseBundle\Entity\CCourseDescription;
use Chamilo\CourseBundle\Entity\CTool;
use Chamilo\CourseBundle\Entity\CToolIntro;
use Chamilo\CourseBundle\Repository\CCourseDescriptionRepository;
use Chamilo\CourseBundle\Repository\CQuizRepository;
use Chamilo\CourseBundle\Repository\CShortcutRepository;
use Chamilo\CourseBundle\Repository\CToolRepository;
use Chamilo\CourseBundle\Settings\SettingsCourseManager;
@ -761,6 +762,28 @@ 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);
}
private function autoLaunch(): void
{
$autoLaunchWarning = '';

@ -88,6 +88,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();
@ -143,6 +144,7 @@ class PlatformConfigurationController extends AbstractController
'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'),
];
return new JsonResponse(['settings' => $settings]);

@ -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