Passed
Push — master ( b36cbe...35a819 )
by Angel Fernando Quiroz
09:33
created

TrackECourseAccessRepository::logoutAccess()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 38
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 30
c 0
b 0
f 0
nc 2
nop 4
dl 0
loc 38
rs 9.44
1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Repository;
8
9
use Chamilo\CoreBundle\Entity\Course;
10
use Chamilo\CoreBundle\Entity\Session;
11
use Chamilo\CoreBundle\Entity\TrackECourseAccess;
12
use Chamilo\CoreBundle\Entity\User;
13
use DateTime;
14
use DateTimeZone;
15
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
16
use Doctrine\ORM\NonUniqueResultException;
17
use Doctrine\ORM\NoResultException;
18
use Doctrine\Persistence\ManagerRegistry;
19
20
/**
21
 * @author Angel Fernando Quiroz Campos <[email protected]>
22
 */
23
class TrackECourseAccessRepository extends ServiceEntityRepository
24
{
25
    public function __construct(ManagerRegistry $registry)
26
    {
27
        parent::__construct($registry, TrackECourseAccess::class);
28
    }
29
30
    /**
31
     * Get the last registered access by an user.
32
     */
33
    public function getLastAccessByUser(?User $user = null): ?TrackECourseAccess
34
    {
35
        if (null === $user) {
36
            return null;
37
        }
38
39
        $lastAccess = $this->findBy(
40
            [
41
                'userId' => $user->getId(),
42
            ],
43
            [
44
                'courseAccessId' => 'DESC',
45
            ],
46
            1
47
        );
48
49
        if (!empty($lastAccess)) {
50
            return $lastAccess[0];
51
        }
52
53
        return null;
54
    }
55
56
    /**
57
     * Find existing access for a user.
58
     */
59
    public function findExistingAccess(User $user, int $courseId, int $sessionId)
60
    {
61
        return $this->findOneBy(['user' => $user, 'cId' => $courseId, 'sessionId' => $sessionId]);
62
    }
63
64
    /**
65
     * Update access record.
66
     */
67
    public function updateAccess(TrackECourseAccess $access): void
68
    {
69
        $now = new DateTime();
70
        if (!$access->getLogoutCourseDate() || $now->getTimestamp() - $access->getLogoutCourseDate()->getTimestamp() > 300) {
71
            $access->setLogoutCourseDate($now);
72
            $access->setCounter($access->getCounter() + 1);
73
            $this->_em->flush();
74
        }
75
    }
76
77
    /**
78
     * Record a new access entry.
79
     */
80
    public function recordAccess(User $user, int $courseId, int $sessionId, string $ip): void
81
    {
82
        $access = new TrackECourseAccess();
83
        $access->setUser($user);
84
        $access->setCId($courseId);
85
        $access->setSessionId($sessionId);
86
        $access->setUserIp($ip);
87
        $access->setLoginCourseDate(new DateTime());
88
        $access->setCounter(1);
89
        $this->_em->persist($access);
90
        $this->_em->flush();
91
    }
92
93
    /**
94
     * Log out user access to a course.
95
     */
96
    public function logoutAccess(User $user, int $courseId, int $sessionId, string $ip): void
97
    {
98
        $now = new DateTime('now', new DateTimeZone('UTC'));
99
        $sessionLifetime = 3600;
100
        $limitTime = (new DateTime())->setTimestamp(time() - $sessionLifetime);
101
102
        $access = $this->createQueryBuilder('a')
103
            ->where('a.user = :user AND a.cId = :courseId AND a.sessionId = :sessionId')
104
            ->andWhere('a.loginCourseDate > :limitTime')
105
            ->setParameters([
106
                'user' => $user,
107
                'courseId' => $courseId,
108
                'sessionId' => $sessionId,
109
                'limitTime' => $limitTime,
110
            ])
111
            ->orderBy('a.loginCourseDate', 'DESC')
112
            ->setMaxResults(1)
113
            ->getQuery()
114
            ->getOneOrNullResult()
115
        ;
116
117
        if ($access) {
118
            $access->setLogoutCourseDate($now);
119
            $access->setCounter($access->getCounter() + 1);
120
            $this->_em->flush();
121
        } else {
122
            // No access found or existing access is outside the session lifetime
123
            // Insert new access record
124
            $newAccess = new TrackECourseAccess();
125
            $newAccess->setUser($user);
126
            $newAccess->setCId($courseId);
127
            $newAccess->setSessionId($sessionId);
128
            $newAccess->setUserIp($ip);
129
            $newAccess->setLoginCourseDate($now);
130
            $newAccess->setLogoutCourseDate($now);
131
            $newAccess->setCounter(1);
132
            $this->_em->persist($newAccess);
133
            $this->_em->flush();
134
        }
135
    }
136
137
    public function getCourseVisits(Course $course, ?Session $session = null): int
138
    {
139
        $qb = $this->createQueryBuilder('tca');
140
141
        $qb
142
            ->select($qb->expr()->count('tca'))
143
            ->where($qb->expr()->eq('tca.cId', ':courseId'))
144
            ->setParameter('courseId', $course->getId())
145
        ;
146
147
        if ($session) {
148
            $qb
149
                ->andWhere($qb->expr()->eq('tca.sessionId', ':sessionId'))
150
                ->setParameter('sessionId', $session->getId())
151
            ;
152
        }
153
154
        try {
155
            $result = $qb
156
                ->setMaxResults(1)
157
                ->getQuery()
158
                ->getSingleScalarResult();
159
        } catch (NoResultException|NonUniqueResultException) {
160
            $result = 0;
161
        }
162
163
        return (int) $result;
164
    }
165
}
166