+ {{ $t("Loading sessions. Please wait.") }}
+
+
+
-
-
-
-
- {{ $t("There are no sessions available") }}
-
-
- {{ $t("Loading sessions. Please wait.") }}
-
-
+
+
+
-
-
- {{ data.title }}
-
-
-
-
-
-
-
-
-
-
-
-
- {{ data.category.title }}
-
-
-
-
-
- {{ formatDate(data.displayStartDate) }}
-
-
-
-
-
-
- {{ $t("Go to the session") }}
-
-
-
-
-
-
{{ $t("Courses in this session") + " - " + item.data.title }}
-
-
-
-
-
-
-
-
- {{ data.course.title }}
-
-
-
-
- {{ getOriginalLanguageName(data.course.courseLanguage) }}
-
-
-
-
-
-
- {{ category.title }}
-
-
-
-
-
-
-
- {{ $t("Go to the course") }}
-
-
-
-
-
-
-
- {{ $t("Number of sessions").concat(": ", sessions ? sessions.length.toString() : "0") }}
-
-
+
+
+
+ {{ $t("Loading more sessions...") }}
+
-
+
diff --git a/src/CoreBundle/Controller/CatalogueController.php b/src/CoreBundle/Controller/CatalogueController.php
index 62afe2e49d5..c6a100f5da8 100644
--- a/src/CoreBundle/Controller/CatalogueController.php
+++ b/src/CoreBundle/Controller/CatalogueController.php
@@ -11,6 +11,7 @@
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CoreBundle\Entity\UsergroupRelUser;
+use Chamilo\CoreBundle\Entity\UserRelCourseVote;
use Chamilo\CoreBundle\Repository\Node\CourseRepository;
use Chamilo\CoreBundle\Repository\SessionRepository;
use Chamilo\CoreBundle\ServiceHelper\AccessUrlHelper;
@@ -83,6 +84,7 @@ public function listSessions(): JsonResponse
$relRepo = $this->em->getRepository(CatalogueSessionRelAccessUrlRelUsergroup::class);
$userGroupRepo = $this->em->getRepository(UsergroupRelUser::class);
+ $voteRepo = $this->em->getRepository(UserRelCourseVote::class);
$relations = $relRepo->findBy(['accessUrl' => $accessUrl]);
@@ -98,7 +100,7 @@ public function listSessions(): JsonResponse
$session = $rel->getSession();
$usergroup = $rel->getUsergroup();
- if (null === $usergroup || \in_array($usergroup->getId(), $userGroupIds)) {
+ if (null === $usergroup || in_array($usergroup->getId(), $userGroupIds)) {
$visibleSessions[$session->getId()] = $session;
}
}
@@ -106,7 +108,43 @@ public function listSessions(): JsonResponse
$sessions = array_values($visibleSessions);
}
- $data = array_map(function (Session $session) {
+ $data = array_map(function (Session $session) use ($voteRepo, $user) {
+ $courses = [];
+
+ foreach ($session->getCourses() as $rel) {
+ $course = $rel->getCourse();
+ if (!$course) {
+ continue;
+ }
+
+ $teachers = [];
+ foreach ($session->getGeneralCoachesSubscriptions() as $coachRel) {
+ $userObj = $coachRel->getUser();
+ if ($userObj) {
+ $teachers[] = [
+ 'id' => $userObj->getId(),
+ 'fullName' => $userObj->getFullname(),
+ ];
+ }
+ }
+
+ $courses[] = [
+ 'id' => $course->getId(),
+ 'title' => $course->getTitle(),
+ 'duration' => $course->getDuration(),
+ 'courseLanguage' => $course->getCourseLanguage(),
+ 'teachers' => $teachers,
+ ];
+ }
+
+ $voteCount = (int) $voteRepo->createQueryBuilder('v')
+ ->select('COUNT(DISTINCT v.user)')
+ ->where('v.session = :session')
+ ->andWhere('v.course IS NULL')
+ ->setParameter('session', $session->getId())
+ ->getQuery()
+ ->getSingleScalarResult();
+
return [
'id' => $session->getId(),
'title' => $session->getTitle(),
@@ -117,6 +155,9 @@ public function listSessions(): JsonResponse
'nbrCourses' => $session->getNbrCourses(),
'startDate' => $session->getAccessStartDate()?->format('Y-m-d'),
'endDate' => $session->getAccessEndDate()?->format('Y-m-d'),
+ 'courses' => $courses,
+ 'popularity' => $voteCount,
+ 'isSubscribed' => $session->hasUserInSession($user, Session::STUDENT),
];
}, $sessions);
diff --git a/src/CoreBundle/Entity/Course.php b/src/CoreBundle/Entity/Course.php
index 4945c94f41a..3a45e745e0a 100644
--- a/src/CoreBundle/Entity/Course.php
+++ b/src/CoreBundle/Entity/Course.php
@@ -300,10 +300,12 @@ class Course extends AbstractResource implements ResourceInterface, ResourceWith
protected ?DateTime $expirationDate = null;
#[Assert\NotNull]
+ #[Groups(['course:read'])]
#[ORM\Column(name: 'subscribe', type: 'boolean', unique: false, nullable: false)]
protected bool $subscribe;
#[Assert\NotNull]
+ #[Groups(['course:read'])]
#[ORM\Column(name: 'unsubscribe', type: 'boolean', unique: false, nullable: false)]
protected bool $unsubscribe;
diff --git a/src/CoreBundle/Entity/CourseRelUser.php b/src/CoreBundle/Entity/CourseRelUser.php
index cd08150e1c3..de59e9c518b 100644
--- a/src/CoreBundle/Entity/CourseRelUser.php
+++ b/src/CoreBundle/Entity/CourseRelUser.php
@@ -26,7 +26,7 @@
operations: [
new Get(security: "is_granted('ROLE_ADMIN') or object.user == user"),
new GetCollection(security: "is_granted('ROLE_ADMIN')"),
- new Post(security: "is_granted('ROLE_ADMIN')"),
+ new Post(security: "is_granted('ROLE_ADMIN') or is_granted('ROLE_USER')"),
],
normalizationContext: [
'groups' => ['course_rel_user:read'],
diff --git a/src/CoreBundle/Entity/SessionRelUser.php b/src/CoreBundle/Entity/SessionRelUser.php
index 5b4d104e726..5f56216787f 100644
--- a/src/CoreBundle/Entity/SessionRelUser.php
+++ b/src/CoreBundle/Entity/SessionRelUser.php
@@ -30,7 +30,7 @@
operations: [
new Get(security: "is_granted('ROLE_ADMIN') or object.user == user"),
new GetCollection(security: "is_granted('ROLE_USER')"),
- new Post(security: "is_granted('ROLE_ADMIN')"),
+ new Post(security: "is_granted('ROLE_ADMIN') or is_granted('ROLE_USER')"),
],
normalizationContext: [
'groups' => [
diff --git a/src/CoreBundle/Entity/UserRelCourseVote.php b/src/CoreBundle/Entity/UserRelCourseVote.php
index 1f6e39b5446..efb34c66a38 100644
--- a/src/CoreBundle/Entity/UserRelCourseVote.php
+++ b/src/CoreBundle/Entity/UserRelCourseVote.php
@@ -62,9 +62,9 @@ class UserRelCourseVote
protected User $user;
#[ORM\ManyToOne(targetEntity: Course::class)]
- #[ORM\JoinColumn(name: 'c_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
+ #[ORM\JoinColumn(name: 'c_id', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')]
#[Groups(['userRelCourseVote:read', 'userRelCourseVote:write'])]
- protected Course $course;
+ protected ?Course $course = null;
#[ORM\ManyToOne(targetEntity: Session::class)]
#[ORM\JoinColumn(name: 'session_id', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')]
@@ -109,12 +109,12 @@ public function setUser(User $user): self
return $this;
}
- public function getCourse(): Course
+ public function getCourse(): ?Course
{
return $this->course;
}
- public function setCourse(Course $course): self
+ public function setCourse(?Course $course): self
{
$this->course = $course;
diff --git a/src/CoreBundle/EventListener/UserRelCourseVoteListener.php b/src/CoreBundle/EventListener/UserRelCourseVoteListener.php
index 44388703342..e041dc0fdb6 100644
--- a/src/CoreBundle/EventListener/UserRelCourseVoteListener.php
+++ b/src/CoreBundle/EventListener/UserRelCourseVoteListener.php
@@ -34,14 +34,17 @@ private function updateCoursePopularity(UserRelCourseVote $vote, EntityManagerIn
{
$course = $vote->getCourse();
+ if (!$course) {
+ return;
+ }
+
$uniqueUsers = (int) $entityManager->createQueryBuilder()
->select('COUNT(DISTINCT v.user)')
->from(UserRelCourseVote::class, 'v')
->where('v.course = :course')
->setParameter('course', $course->getId())
->getQuery()
- ->getSingleScalarResult()
- ;
+ ->getSingleScalarResult();
$course->setPopularity($uniqueUsers);
$entityManager->persist($course);