Skip to content

Commit e550fc5

Browse files
Internal: Refactor course access tracking- BT#21694
1 parent 112488d commit e550fc5

File tree

6 files changed

+103
-84
lines changed

6 files changed

+103
-84
lines changed

public/main/inc/lib/tracking.lib.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5712,7 +5712,7 @@ public static function show_course_detail($userId, $courseId, $sessionId = 0, $s
57125712
);
57135713
$last_connection_in_lp = self::get_last_connection_time_in_lp(
57145714
$userId,
5715-
$course,
5715+
$course->getCode(),
57165716
$lp_id,
57175717
$sessionId
57185718
);

public/main/my_space/myStudents.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1705,7 +1705,7 @@
17051705
// Get last connection time in lp
17061706
$start_time = Tracking::get_last_connection_time_in_lp(
17071707
$studentId,
1708-
$course,
1708+
$course->getCode(),
17091709
$lp_id,
17101710
$sessionId
17111711
);

src/CoreBundle/EventListener/CidReqListener.php

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function __construct(
4141
private readonly AuthorizationCheckerInterface $authorizationChecker,
4242
private readonly TranslatorInterface $translator,
4343
private readonly EntityManagerInterface $entityManager,
44-
private readonly TokenStorageInterface $tokenStorage,
44+
private readonly TokenStorageInterface $tokenStorage
4545
) {}
4646

4747
/**
@@ -270,12 +270,19 @@ public function cleanSessionHandler(Request $request): void
270270
ChamiloSession::erase('course_already_visited');
271271
}
272272

273-
$user = $this->tokenStorage->getToken()->getUser();
274273
$courseId = $sessionHandler->get('cid', 0);
275274
$sessionId = $sessionHandler->get('sid', 0);
276275
$ip = $request->getClientIp();
277276
if ($courseId !== 0) {
278-
$this->logoutAccess($user, $courseId, $sessionId, $ip);
277+
$token = $this->tokenStorage->getToken();
278+
if (null !== $token) {
279+
/** @var User $user */
280+
$user = $token->getUser();
281+
if ($user instanceof UserInterface) {
282+
$this->entityManager->getRepository(TrackECourseAccess::class)
283+
->logoutAccess($user, $courseId, $sessionId, $ip);
284+
}
285+
}
279286
}
280287
$sessionHandler->remove('toolgroup');
281288
$sessionHandler->remove('_cid');
@@ -335,45 +342,4 @@ private function generateCourseUrl(?Course $course, int $sessionId, int $groupId
335342

336343
return '';
337344
}
338-
339-
private function logoutAccess(User $user, int $courseId, int $sessionId, string $ip): void
340-
{
341-
$now = new DateTime("now", new \DateTimeZone("UTC"));
342-
$sessionLifetime = 3600;
343-
$limitTime = (new DateTime())->setTimestamp(time() - $sessionLifetime);
344-
345-
$access = $this->entityManager->getRepository(TrackECourseAccess::class)
346-
->createQueryBuilder('a')
347-
->where('a.user = :user AND a.cId = :courseId AND a.sessionId = :sessionId')
348-
->andWhere('a.loginCourseDate > :limitTime')
349-
->setParameters([
350-
'user' => $user,
351-
'courseId' => $courseId,
352-
'sessionId' => $sessionId,
353-
'limitTime' => $limitTime,
354-
])
355-
->orderBy('a.loginCourseDate', 'DESC')
356-
->setMaxResults(1)
357-
->getQuery()
358-
->getOneOrNullResult();
359-
360-
if ($access) {
361-
$access->setLogoutCourseDate($now);
362-
$access->setCounter($access->getCounter() + 1);
363-
$this->entityManager->flush();
364-
} else {
365-
// No access found or existing access is outside the session lifetime
366-
// Insert new access record
367-
$newAccess = new TrackECourseAccess();
368-
$newAccess->setUser($user);
369-
$newAccess->setCId($courseId);
370-
$newAccess->setSessionId($sessionId);
371-
$newAccess->setUserIp($ip);
372-
$newAccess->setLoginCourseDate($now);
373-
$newAccess->setLogoutCourseDate($now);
374-
$newAccess->setCounter(1);
375-
$this->entityManager->persist($newAccess);
376-
$this->entityManager->flush();
377-
}
378-
}
379345
}

src/CoreBundle/EventListener/CourseAccessListener.php

Lines changed: 9 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Chamilo\CoreBundle\Entity\TrackECourseAccess;
1010
use Chamilo\CoreBundle\Entity\User;
1111
use Chamilo\CoreBundle\ServiceHelper\CidReqHelper;
12+
use Chamilo\CoreBundle\ServiceHelper\UserHelper;
1213
use DateTime;
1314
use Symfony\Component\HttpKernel\Event\RequestEvent;
1415
use Doctrine\ORM\EntityManagerInterface;
@@ -23,9 +24,8 @@ class CourseAccessListener
2324
{
2425
public function __construct(
2526
private readonly EntityManagerInterface $em,
26-
private readonly RequestStack $requestStack,
2727
private readonly CidReqHelper $cidReqHelper,
28-
private readonly TokenStorageInterface $tokenStorage,
28+
private readonly UserHelper $userHelper
2929
) {}
3030

3131
public function onKernelRequest(RequestEvent $event): void
@@ -39,49 +39,21 @@ public function onKernelRequest(RequestEvent $event): void
3939
$sessionId = (int) $this->cidReqHelper->getSessionId();
4040

4141
if ($courseId > 0) {
42-
$user = $this->tokenStorage->getToken()?->getUser();
43-
if ($user instanceof User) {
44-
$ip = $this->requestStack->getCurrentRequest()->getClientIp();
45-
$access = $this->findExistingAccess($user, $courseId, $sessionId);
42+
$user = $this->userHelper->getCurrent();
43+
if ($user) {
44+
$ip = $event->getRequest()->getClientIp();
45+
$accessRepository = $this->em->getRepository(TrackECourseAccess::class);
46+
$access = $accessRepository->findExistingAccess($user, $courseId, $sessionId);
4647

4748
if ($access) {
48-
$this->updateAccess($access);
49+
$accessRepository->updateAccess($access);
4950
} else {
50-
$this->recordAccess($user, $courseId, $sessionId, $ip);
51+
$accessRepository->recordAccess($user, $courseId, $sessionId, $ip);
5152
}
5253

5354
// Set a flag on the request to indicate that access has been checked
5455
$event->getRequest()->attributes->set('access_checked', true);
5556
}
5657
}
5758
}
58-
59-
private function findExistingAccess(User $user, int $courseId, int $sessionId)
60-
{
61-
return $this->em->getRepository(TrackECourseAccess::class)
62-
->findOneBy(['user' => $user, 'cId' => $courseId, 'sessionId' => $sessionId]);
63-
}
64-
65-
private function updateAccess(TrackECourseAccess $access): void
66-
{
67-
$now = new DateTime();
68-
if (!$access->getLogoutCourseDate() || $now->getTimestamp() - $access->getLogoutCourseDate()->getTimestamp() > 300) {
69-
$access->setLogoutCourseDate($now);
70-
$access->setCounter($access->getCounter() + 1);
71-
$this->em->flush();
72-
}
73-
}
74-
75-
private function recordAccess(User $user, int $courseId, int $sessionId, string $ip): void
76-
{
77-
$access = new TrackECourseAccess();
78-
$access->setUser($user);
79-
$access->setCId($courseId);
80-
$access->setSessionId($sessionId);
81-
$access->setUserIp($ip);
82-
$access->setLoginCourseDate(new \DateTime());
83-
$access->setCounter(1);
84-
$this->em->persist($access);
85-
$this->em->flush();
86-
}
8759
}

src/CoreBundle/Repository/TrackECourseAccessRepository.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
use Chamilo\CoreBundle\Entity\TrackECourseAccess;
1010
use Chamilo\CoreBundle\Entity\User;
11+
use DateTime;
1112
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
1213
use Doctrine\Persistence\ManagerRegistry;
1314

@@ -46,4 +47,84 @@ public function getLastAccessByUser(?User $user = null): ?TrackECourseAccess
4647

4748
return null;
4849
}
50+
51+
/**
52+
* Find existing access for a user.
53+
*/
54+
public function findExistingAccess(User $user, int $courseId, int $sessionId)
55+
{
56+
return $this->findOneBy(['user' => $user, 'cId' => $courseId, 'sessionId' => $sessionId]);
57+
}
58+
59+
/**
60+
* Update access record.
61+
*/
62+
public function updateAccess(TrackECourseAccess $access): void
63+
{
64+
$now = new DateTime();
65+
if (!$access->getLogoutCourseDate() || $now->getTimestamp() - $access->getLogoutCourseDate()->getTimestamp() > 300) {
66+
$access->setLogoutCourseDate($now);
67+
$access->setCounter($access->getCounter() + 1);
68+
$this->_em->flush();
69+
}
70+
}
71+
72+
/**
73+
* Record a new access entry.
74+
*/
75+
public function recordAccess(User $user, int $courseId, int $sessionId, string $ip): void
76+
{
77+
$access = new TrackECourseAccess();
78+
$access->setUser($user);
79+
$access->setCId($courseId);
80+
$access->setSessionId($sessionId);
81+
$access->setUserIp($ip);
82+
$access->setLoginCourseDate(new \DateTime());
83+
$access->setCounter(1);
84+
$this->_em->persist($access);
85+
$this->_em->flush();
86+
}
87+
88+
/**
89+
* Log out user access to a course.
90+
*/
91+
public function logoutAccess(User $user, int $courseId, int $sessionId, string $ip): void
92+
{
93+
$now = new DateTime("now", new \DateTimeZone("UTC"));
94+
$sessionLifetime = 3600;
95+
$limitTime = (new DateTime())->setTimestamp(time() - $sessionLifetime);
96+
97+
$access = $this->createQueryBuilder('a')
98+
->where('a.user = :user AND a.cId = :courseId AND a.sessionId = :sessionId')
99+
->andWhere('a.loginCourseDate > :limitTime')
100+
->setParameters([
101+
'user' => $user,
102+
'courseId' => $courseId,
103+
'sessionId' => $sessionId,
104+
'limitTime' => $limitTime,
105+
])
106+
->orderBy('a.loginCourseDate', 'DESC')
107+
->setMaxResults(1)
108+
->getQuery()
109+
->getOneOrNullResult();
110+
111+
if ($access) {
112+
$access->setLogoutCourseDate($now);
113+
$access->setCounter($access->getCounter() + 1);
114+
$this->_em->flush();
115+
} else {
116+
// No access found or existing access is outside the session lifetime
117+
// Insert new access record
118+
$newAccess = new TrackECourseAccess();
119+
$newAccess->setUser($user);
120+
$newAccess->setCId($courseId);
121+
$newAccess->setSessionId($sessionId);
122+
$newAccess->setUserIp($ip);
123+
$newAccess->setLoginCourseDate($now);
124+
$newAccess->setLogoutCourseDate($now);
125+
$newAccess->setCounter(1);
126+
$this->_em->persist($newAccess);
127+
$this->_em->flush();
128+
}
129+
}
49130
}

src/CoreBundle/Resources/config/listeners.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ services:
1818
# Sets the user access in a course listener
1919
Chamilo\CoreBundle\EventListener\CourseAccessListener:
2020
tags:
21-
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 6 }
21+
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
2222

2323

2424
# Sets the user access in a course session listener

0 commit comments

Comments
 (0)