+
+
+
+
+
diff --git a/assets/vue/components/course/NextCourseSequence.vue b/assets/vue/components/course/NextCourseSequence.vue
new file mode 100644
index 00000000000..ce597352b9e
--- /dev/null
+++ b/assets/vue/components/course/NextCourseSequence.vue
@@ -0,0 +1,97 @@
+
+
+
+ {{ t("Dependencies") }}
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+
+
+
+
+
+ {{ course.name }}
+
+
+
+ {{ course.name }}
+
+
+
+
+
+ {{ course.status ? t("Complete") : t("Incomplete") }}
+
+
+
+
+
+
+
+
+
+
![Graph Dependency Tree]()
+
+
+
+
+
diff --git a/assets/vue/components/session/CatalogueSessionCard.vue b/assets/vue/components/session/CatalogueSessionCard.vue
index 27f4a420074..1c00eb97228 100644
--- a/assets/vue/components/session/CatalogueSessionCard.vue
+++ b/assets/vue/components/session/CatalogueSessionCard.vue
@@ -159,7 +159,16 @@
class="flex justify-between items-center border-b pb-1"
>
{{ item.title }}
+
@@ -189,9 +198,17 @@
v-html="session.description || $t('No description available')"
/>
+
diff --git a/assets/vue/components/session/SessionCardSimple.vue b/assets/vue/components/session/SessionCardSimple.vue
index ce3c61b7c91..c42db2975bc 100644
--- a/assets/vue/components/session/SessionCardSimple.vue
+++ b/assets/vue/components/session/SessionCardSimple.vue
@@ -10,19 +10,35 @@ const props = defineProps({
})
const { courses, isEnabled } = useSessionCard(props.session)
+
+function extractIdFromIri(iri) {
+ if (!iri) return undefined
+ const match = iri.match(/\/(\d+)$/)
+ return match ? parseInt(match[1], 10) : undefined
+}
+
+function normalizeCourse(course) {
+ return {
+ ...course,
+ id: course.id || course._id || extractIdFromIri(course["@id"]),
+ }
+}
-
-
+
diff --git a/assets/vue/components/session/SessionCategoryView.vue b/assets/vue/components/session/SessionCategoryView.vue
index 08ff18eeb57..4c258d5b0d5 100644
--- a/assets/vue/components/session/SessionCategoryView.vue
+++ b/assets/vue/components/session/SessionCategoryView.vue
@@ -1,27 +1,34 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/vue/components/session/SessionListView.vue b/assets/vue/components/session/SessionListView.vue
new file mode 100644
index 00000000000..4113d779010
--- /dev/null
+++ b/assets/vue/components/session/SessionListView.vue
@@ -0,0 +1,98 @@
+
+
+
{{ t("My Sessions") }}
+
+
+
+
+
+
+
+ {{ session.name || session.title || "Untitled Session" }}
+
+
+ {{ session.displayStartDate ? formatDate(session.displayStartDate) : "" }}
+ -
+ {{ session.displayEndDate ? formatDate(session.displayEndDate) : "" }}
+
+
+
+
+ {{ t("Edit") }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/vue/composables/course/useCourseRequirementStatus.js b/assets/vue/composables/course/useCourseRequirementStatus.js
new file mode 100644
index 00000000000..253f6816a60
--- /dev/null
+++ b/assets/vue/composables/course/useCourseRequirementStatus.js
@@ -0,0 +1,52 @@
+import { ref } from "vue"
+import courseService from "../../services/courseService"
+
+export function useCourseRequirementStatus(courseId, sessionId, onLockChange = null) {
+ const isLocked = ref(false)
+ const hasRequirements = ref(false)
+ const requirementList = ref([])
+ const graphImage = ref(null)
+ const loading = ref(true)
+
+ async function fetchStatus() {
+ if (!courseId || courseId === 0) {
+ loading.value = false
+ return
+ }
+
+ loading.value = true
+ try {
+ const result = await courseService.getNextCourse(courseId, sessionId)
+ const locked = !(result?.allowSubscription ?? true)
+
+ isLocked.value = locked
+ hasRequirements.value = result?.sequenceList?.length > 0
+ requirementList.value = result?.sequenceList ?? []
+ graphImage.value = result?.graph || null
+
+ if (onLockChange) {
+ onLockChange(locked)
+ }
+ } catch (e) {
+ isLocked.value = false
+ hasRequirements.value = false
+ requirementList.value = []
+ graphImage.value = null
+
+ if (onLockChange) {
+ onLockChange(false)
+ }
+ } finally {
+ loading.value = false
+ }
+ }
+
+ return {
+ isLocked,
+ hasRequirements,
+ requirementList,
+ graphImage,
+ loading,
+ fetchStatus,
+ }
+}
diff --git a/assets/vue/services/courseService.js b/assets/vue/services/courseService.js
index 9e1bd779516..2686aca12b1 100644
--- a/assets/vue/services/courseService.js
+++ b/assets/vue/services/courseService.js
@@ -204,4 +204,14 @@ export default {
return []
}
},
+
+ getNextCourse: async (courseId, sessionId = 0, dependents = false) => {
+ const { data } = await api.get(`/course/${courseId}/next-course`, {
+ params: {
+ sid: sessionId,
+ dependents: dependents ? 1 : 0,
+ },
+ })
+ return data
+ }
}
diff --git a/assets/vue/views/course/CourseHome.vue b/assets/vue/views/course/CourseHome.vue
index c0edd3c4063..5aca54c8b58 100644
--- a/assets/vue/views/course/CourseHome.vue
+++ b/assets/vue/views/course/CourseHome.vue
@@ -143,10 +143,20 @@
-
+
{
+ return platformConfigStore.getSetting("course.resource_sequence_show_dependency_in_course_intro") === "true"
+})
onMounted(async () => {
isAllowedToEdit.value = await checkIsAllowedToEdit()
diff --git a/public/main/session/resume_session.php b/public/main/session/resume_session.php
index 1df62218e25..1b9070a948d 100644
--- a/public/main/session/resume_session.php
+++ b/public/main/session/resume_session.php
@@ -7,10 +7,9 @@
use Chamilo\CoreBundle\Entity\SessionRelCourse;
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
use Chamilo\CoreBundle\Framework\Container;
-use Chamilo\CoreBundle\Repository\SequenceRepository;
use Chamilo\CoreBundle\Component\Utils\ActionIcon;
use Chamilo\CoreBundle\Component\Utils\ObjectIcon;
-use Chamilo\CoreBundle\Component\Utils\StateIcon;
+use Chamilo\CoreBundle\Repository\SequenceResourceRepository;
$cidReset = true;
require_once __DIR__.'/../inc/global.inc.php';
@@ -373,7 +372,7 @@
$userListToShow .= $table->toHtml();
}
-/** @var SequenceRepository $repo */
+/** @var SequenceResourceRepository $repo */
$repo = $em->getRepository(SequenceResource::class);
$requirementAndDependencies = $repo->getRequirementAndDependencies(
$sessionId,
diff --git a/public/main/template/default/admin/resource_sequence.html.twig b/public/main/template/default/admin/resource_sequence.html.twig
index 08cdabaa2fd..09e9e255da8 100644
--- a/public/main/template/default/admin/resource_sequence.html.twig
+++ b/public/main/template/default/admin/resource_sequence.html.twig
@@ -158,7 +158,7 @@
$('button[name="use_as_reference"]').on('click', function (e) {
e.preventDefault();
$('button[name="set_requirement"]').prop('disabled', false);
- $('#requirements').prop('disabled', false).selectpicker('refresh');
+ $('#requirements').prop('disabled', false);
$('button[name="save_resource"]').prop('disabled', false);
useAsReference(type, sequenceId);
diff --git a/src/CoreBundle/Controller/Admin/IndexBlocksController.php b/src/CoreBundle/Controller/Admin/IndexBlocksController.php
index 995a45ebb0f..9acabf3634e 100644
--- a/src/CoreBundle/Controller/Admin/IndexBlocksController.php
+++ b/src/CoreBundle/Controller/Admin/IndexBlocksController.php
@@ -375,10 +375,7 @@ private function getItemsCourses(): array
];
$items[] = [
'class' => 'item-resource-sequence',
- 'url' => $this->generateUrl('legacy_main', [
- 'name' => 'admin/resource_sequence.php',
- 'query' => ['type' => SequenceResource::COURSE_TYPE],
- ]),
+ 'url' => $this->generateUrl('legacy_main', ['name' => 'admin/resource_sequence.php', 'type' => SequenceResource::COURSE_TYPE]),
'label' => $this->translator->trans('Resources sequencing'),
];
@@ -832,10 +829,7 @@ private function getItemsSessions(): array
];
$items[] = [
'class' => 'item-resource-sequence',
- 'url' => $this->generateUrl('legacy_main', [
- 'name' => 'admin/resource_sequence.php',
- 'query' => ['type' => SequenceResource::SESSION_TYPE],
- ]),
+ 'url' => $this->generateUrl('legacy_main', ['name' => 'admin/resource_sequence.php', 'type' => SequenceResource::SESSION_TYPE]),
'label' => $this->translator->trans('Resources sequencing'),
];
$items[] = [
diff --git a/src/CoreBundle/Controller/CourseController.php b/src/CoreBundle/Controller/CourseController.php
index aa7d857ffcc..c75f4825acf 100644
--- a/src/CoreBundle/Controller/CourseController.php
+++ b/src/CoreBundle/Controller/CourseController.php
@@ -9,6 +9,7 @@
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\CourseRelUser;
use Chamilo\CoreBundle\Entity\ExtraField;
+use Chamilo\CoreBundle\Entity\SequenceResource;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CoreBundle\Entity\SessionRelUser;
use Chamilo\CoreBundle\Entity\Tag;
@@ -22,6 +23,7 @@
use Chamilo\CoreBundle\Repository\LegalRepository;
use Chamilo\CoreBundle\Repository\Node\CourseRepository;
use Chamilo\CoreBundle\Repository\Node\IllustrationRepository;
+use Chamilo\CoreBundle\Repository\SequenceResourceRepository;
use Chamilo\CoreBundle\Repository\TagRepository;
use Chamilo\CoreBundle\Security\Authorization\Voter\CourseVoter;
use Chamilo\CoreBundle\Service\CourseService;
@@ -50,7 +52,10 @@
use Exception;
use Exercise;
use ExtraFieldValue;
+use Fhaculty\Graph\Graph;
+use Graphp\GraphViz\GraphViz;
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
+use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
@@ -256,6 +261,64 @@ public function indexJson(
]
);
}
+ #[Route('/{courseId}/next-course', name: 'chamilo_course_next_course')]
+ public function getNextCourse(
+ int $courseId,
+ Request $request,
+ SequenceResourceRepository $repo,
+ Security $security,
+ SettingsManager $settingsManager,
+ EntityManagerInterface $em
+ ): JsonResponse {
+ $sessionId = $request->query->getInt('sid');
+ $useDependents = $request->query->getBoolean('dependents', false);
+ $user = $security->getUser();
+ $userId = $user->getId();
+
+ if ($useDependents) {
+ $sequences = $repo->getDependents($courseId, SequenceResource::COURSE_TYPE);
+ $checked = $repo->checkDependentsForUser($sequences, SequenceResource::COURSE_TYPE, $userId, $sessionId);
+ $isUnlocked = $repo->checkSequenceAreCompleted($checked);
+ $sequenceResource = $repo->findRequirementForResource($courseId, SequenceResource::COURSE_TYPE);
+ } else {
+ $sequences = $repo->getRequirements($courseId, SequenceResource::COURSE_TYPE);
+
+ $hasValidRequirement = false;
+ foreach ($sequences as $sequence) {
+ foreach ($sequence['requirements'] ?? [] as $resource) {
+ if ($resource instanceof Course) {
+ $hasValidRequirement = true;
+ break 2;
+ }
+ }
+ }
+
+ if (!$hasValidRequirement) {
+ return new JsonResponse([]);
+ }
+
+ $checked = $repo->checkRequirementsForUser($sequences, SequenceResource::COURSE_TYPE, $userId, $sessionId);
+ $isUnlocked = $repo->checkSequenceAreCompleted($checked);
+ $sequenceResource = $repo->findRequirementForResource($courseId, SequenceResource::COURSE_TYPE);
+ }
+
+ $graphImage = null;
+
+ if ($sequenceResource && $sequenceResource->hasGraph()) {
+ $graph = $sequenceResource->getSequence()->getUnSerializeGraph();
+ if ($graph !== null) {
+ $graph->setAttribute('graphviz.node.fontname', 'arial');
+ $graphviz = new GraphViz();
+ $graphImage = $graphviz->createImageSrc($graph);
+ }
+ }
+
+ return new JsonResponse([
+ 'sequenceList' => array_values($checked),
+ 'allowSubscription' => $isUnlocked,
+ 'graph' => $graphImage,
+ ]);
+ }
/**
* Redirects the page to a tool, following the tools settings.
diff --git a/src/CoreBundle/Controller/PlatformConfigurationController.php b/src/CoreBundle/Controller/PlatformConfigurationController.php
index 08f7dcb1232..913ea8d9fec 100644
--- a/src/CoreBundle/Controller/PlatformConfigurationController.php
+++ b/src/CoreBundle/Controller/PlatformConfigurationController.php
@@ -113,6 +113,8 @@ public function list(SettingsManager $settingsManager): Response
'session.session_automatic_creation_user_id',
'session.session_list_view_remaining_days',
'profile.use_users_timezone',
+ 'session.user_session_display_mode',
+ 'course.resource_sequence_show_dependency_in_course_intro',
];
$user = $this->userHelper->getCurrent();
diff --git a/src/CoreBundle/DataFixtures/SettingsCurrentFixtures.php b/src/CoreBundle/DataFixtures/SettingsCurrentFixtures.php
index fc9c90feb19..3a1d19cb7ba 100644
--- a/src/CoreBundle/DataFixtures/SettingsCurrentFixtures.php
+++ b/src/CoreBundle/DataFixtures/SettingsCurrentFixtures.php
@@ -114,6 +114,11 @@ public static function getExistingSettings(): array
],
],
'session' => [
+ [
+ 'name' => 'user_session_display_mode',
+ 'title' => 'My Sessions display mode',
+ 'comment' => 'Choose how the "My Sessions" page is displayed: as a modern visual block (card) view or the classic list style.',
+ ],
[
'name' => 'session_list_view_remaining_days',
'title' => 'Show remaining days in My Sessions',
@@ -248,6 +253,11 @@ public static function getExistingSettings(): array
],
],
'course' => [
+ [
+ 'name' => 'course_sequence_valid_only_in_same_session',
+ 'title' => 'Validate prerequisites only within the same session',
+ 'comment' => 'When enabled, a course will be considered validated only if passed within the current session. If disabled, courses passed in other sessions will also unlock dependent courses.',
+ ],
[
'name' => 'access_url_specific_files',
'title' => 'Enable URL-specific files',
diff --git a/src/CoreBundle/Repository/SequenceResourceRepository.php b/src/CoreBundle/Repository/SequenceResourceRepository.php
index e0fc1b74268..bae9a8b3144 100644
--- a/src/CoreBundle/Repository/SequenceResourceRepository.php
+++ b/src/CoreBundle/Repository/SequenceResourceRepository.php
@@ -11,7 +11,9 @@
use Chamilo\CoreBundle\Entity\GradebookCategory;
use Chamilo\CoreBundle\Entity\SequenceResource;
use Chamilo\CoreBundle\Entity\Session;
+use Chamilo\CoreBundle\Entity\SessionRelCourse;
use Chamilo\CoreBundle\Entity\SessionRelUser;
+use Chamilo\CoreBundle\Settings\SettingsManager;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Fhaculty\Graph\Set\Vertices;
@@ -20,8 +22,10 @@
class SequenceResourceRepository extends ServiceEntityRepository
{
- public function __construct(ManagerRegistry $registry)
- {
+ public function __construct(
+ ManagerRegistry $registry,
+ private readonly SettingsManager $settingsManager
+ ) {
parent::__construct($registry, SequenceResource::class);
}
@@ -259,8 +263,8 @@ public function checkRequirementsForUser(array $sequences, int $type, int $userI
$course = $sessionCourse->getCourse();
$categories = $gradebookCategoryRepo->findBy(
[
- 'courseCode' => $course->getCode(),
- 'sessionId' => $resource->getId(),
+ 'course' => $course,
+ 'session' => $resource,
'isRequirement' => true,
]
);
@@ -269,7 +273,10 @@ public function checkRequirementsForUser(array $sequences, int $type, int $userI
if (!empty($userId)) {
$resourceItem['status'] = $resourceItem['status'] && Category::userFinishedCourse(
$userId,
- $category
+ $category,
+ true,
+ $course->getId(),
+ $resource->getId()
);
}
}
@@ -316,15 +323,23 @@ public function checkRequirementsForUser(array $sequences, int $type, int $userI
public function checkCourseRequirements(int $userId, Course $course, int $sessionId = 0): bool
{
$em = $this->getEntityManager();
-
+ $session = $sessionId > 0
+ ? $em->getRepository(Session::class)->find($sessionId)
+ : null;
$gradebookCategoryRepo = $em->getRepository(GradebookCategory::class);
- $categories = $gradebookCategoryRepo->findBy(
- [
- 'courseCode' => $course->getCode(),
- 'sessionId' => $sessionId,
+ $categories = $gradebookCategoryRepo->findBy([
+ 'course' => $course,
+ 'session' => $session,
+ 'isRequirement' => true,
+ ]);
+
+ if (empty($categories) && $sessionId > 0) {
+ $categories = $gradebookCategoryRepo->findBy([
+ 'course' => $course,
+ 'session' => null,
'isRequirement' => true,
- ]
- );
+ ]);
+ }
if (empty($categories)) {
return false;
@@ -335,16 +350,12 @@ public function checkCourseRequirements(int $userId, Course $course, int $sessio
$userFinishedCourse = Category::userFinishedCourse(
$userId,
$category,
- true
+ true,
+ $course->getId(),
+ $sessionId
);
- if (0 === $sessionId) {
- if (!$userFinishedCourse) {
- $status = false;
-
- break;
- }
- } elseif (!$userFinishedCourse) {
+ if (!$userFinishedCourse) {
$status = false;
break;
@@ -364,6 +375,11 @@ public function checkCourseRequirements(int $userId, Course $course, int $sessio
public function checkSequenceAreCompleted(array $sequences)
{
foreach ($sequences as $sequence) {
+
+ if (!isset($sequence['requirements'])) {
+ continue;
+ }
+
$status = true;
foreach ($sequence['requirements'] as $item) {
@@ -414,4 +430,159 @@ protected function findVerticesEdges(Vertices $verticesEdges, int $type)
return $sessionVertices;
}
+
+ public function getDependents(int $resourceId, int $type): array
+ {
+ return $this->getRequirementsOrDependents($resourceId, $type, 'dependents');
+ }
+
+ public function checkDependentsForUser(array $sequences, int $type, int $userId, int $sessionId = 0): array
+ {
+ return $this->checkRequirementsOrDependentsForUser(
+ $sequences,
+ $type,
+ 'dependents',
+ $userId,
+ $sessionId
+ );
+ }
+
+ private function getRequirementsOrDependents(int $resourceId, int $resourceType, string $itemType): array
+ {
+ $em = $this->getEntityManager();
+
+ $sequencesResource = $this->findBy(['resourceId' => $resourceId, 'type' => $resourceType]);
+ $result = [];
+
+ foreach ($sequencesResource as $sequenceResource) {
+ if (!$sequenceResource->hasGraph()) {
+ continue;
+ }
+
+ $sequence = $sequenceResource->getSequence();
+ $graph = $sequence->getUnSerializeGraph();
+ $vertex = $graph->getVertex($resourceId);
+
+ $edges = $itemType === 'requirements'
+ ? $vertex->getVerticesEdgeFrom()
+ : $vertex->getVerticesEdgeTo();
+
+ $sequenceInfo = [
+ 'name' => $sequence->getTitle(),
+ $itemType => [],
+ ];
+
+ foreach ($edges as $edge) {
+ $vertexId = $edge->getId();
+ $resource = null;
+
+ switch ($resourceType) {
+ case SequenceResource::SESSION_TYPE:
+ $resource = $em->getRepository(Session::class)->find($vertexId);
+ break;
+ case SequenceResource::COURSE_TYPE:
+ $resource = $em->getRepository(Course::class)->find($vertexId);
+ break;
+ }
+
+ if (null === $resource) {
+ continue;
+ }
+
+ $sequenceInfo[$itemType][$vertexId] = $resource;
+ }
+
+ $result[$sequence->getId()] = $sequenceInfo;
+ }
+
+ return $result;
+ }
+
+ private function checkRequirementsOrDependentsForUser(
+ array $sequences,
+ int $resourceType,
+ string $itemType,
+ int $userId,
+ int $sessionId = 0
+ ): array {
+ $sequenceList = [];
+ $em = $this->getEntityManager();
+ $gradebookCategoryRepo = $em->getRepository(GradebookCategory::class);
+
+ $sessionUserList = [];
+ $checkOnlySameSession = $this->settingsManager->getSetting('course.course_sequence_valid_only_in_same_session', true);
+
+ if (SequenceResource::COURSE_TYPE === $resourceType) {
+ if ($checkOnlySameSession) {
+ $sessionUserList = [$sessionId];
+ } else {
+ $sessions = $em->getRepository(SessionRelUser::class)->findBy(['user' => $userId]);
+ foreach ($sessions as $sessionRelUser) {
+ $sessionUserList[] = $sessionRelUser->getSession()->getId();
+ }
+ }
+ }
+
+ foreach ($sequences as $sequenceId => $sequence) {
+ $item = ['name' => $sequence['name'], $itemType => []];
+
+ foreach ($sequence[$itemType] as $resource) {
+ switch ($resourceType) {
+ case SequenceResource::SESSION_TYPE:
+ $id = $resource->getId();
+ $resourceItem = ['name' => $resource->getName(), 'status' => true];
+
+ /* @var SessionRelCourse $sessionCourse */
+ foreach ($resource->getCourses() as $sessionCourse) {
+ $course = $sessionCourse->getCourse();
+ $session = $sessionCourse->getSession();
+ $categories = $gradebookCategoryRepo->findBy([
+ 'course' => $course,
+ 'session' => $session,
+ 'isRequirement' => true,
+ ]);
+
+ foreach ($categories as $category) {
+ $resourceItem['status'] = $resourceItem['status'] && Category::userFinishedCourse(
+ $userId,
+ $category,
+ true,
+ $course->getId(),
+ $sessionId
+ );
+ }
+ }
+ break;
+
+ case SequenceResource::COURSE_TYPE:
+ $id = $resource->getId();
+ $status = $this->checkCourseRequirements($userId, $resource, $sessionId);
+
+ if (!$status) {
+ foreach (SessionManager::get_session_by_course($id) as $session) {
+ if (in_array($session['id'], $sessionUserList)) {
+ $status = $this->checkCourseRequirements($userId, $resource, $session['id']);
+ if ($status) break;
+ }
+ }
+ }
+
+ $resourceItem = [
+ 'name' => $resource->getTitle(),
+ 'code' => $resource->getCode(),
+ 'status' => $status,
+ ];
+ break;
+ }
+
+ if (!empty($id)) {
+ $item[$itemType][$id] = $resourceItem;
+ }
+ }
+
+ $sequenceList[$sequenceId] = $item;
+ }
+
+ return $sequenceList;
+ }
}
diff --git a/src/CoreBundle/Settings/CourseSettingsSchema.php b/src/CoreBundle/Settings/CourseSettingsSchema.php
index 3bd07f202d4..538800315bd 100644
--- a/src/CoreBundle/Settings/CourseSettingsSchema.php
+++ b/src/CoreBundle/Settings/CourseSettingsSchema.php
@@ -109,6 +109,7 @@ public function buildSettings(AbstractSettingsBuilder $builder): void
'course_student_info' => '',
'course_catalog_settings' => '',
'resource_sequence_show_dependency_in_course_intro' => 'false',
+ 'course_sequence_valid_only_in_same_session' => 'false',
'course_catalog_display_in_home' => 'false',
'course_creation_form_set_course_category_mandatory' => 'false',
'course_creation_form_hide_course_code' => 'false',
@@ -302,6 +303,7 @@ public function buildForm(FormBuilderInterface $builder): void
]
)
->add('resource_sequence_show_dependency_in_course_intro', YesNoType::class)
+ ->add('course_sequence_valid_only_in_same_session', YesNoType::class)
->add('course_catalog_display_in_home', YesNoType::class)
->add('course_creation_form_set_course_category_mandatory', YesNoType::class)
->add('course_creation_form_hide_course_code', YesNoType::class)
diff --git a/src/CoreBundle/Settings/SessionSettingsSchema.php b/src/CoreBundle/Settings/SessionSettingsSchema.php
index 6f8b9c39827..e610cee22d5 100644
--- a/src/CoreBundle/Settings/SessionSettingsSchema.php
+++ b/src/CoreBundle/Settings/SessionSettingsSchema.php
@@ -83,6 +83,7 @@ public function buildSettings(AbstractSettingsBuilder $builder): void
'enable_auto_reinscription' => 'false',
'enable_session_replication' => 'false',
'session_list_view_remaining_days' => 'false',
+ 'user_session_display_mode' => 'card',
]
)
;
@@ -209,6 +210,12 @@ public function buildForm(FormBuilderInterface $builder): void
->add('session_model_list_field_ordered_by_id', YesNoType::class)
->add('duplicate_specific_session_content_on_session_copy', YesNoType::class)
->add('session_list_view_remaining_days', YesNoType::class)
+ ->add('user_session_display_mode', ChoiceType::class, [
+ 'choices' => [
+ 'Card (visual blocks)' => 'card',
+ 'List (classic)' => 'list',
+ ],
+ ])
;
$this->updateFormFieldsFromSettingsInfo($builder);